一、垃圾回收机制
1、为什么要进行垃圾回收机制
如果不进行垃圾回收,内存迟早都会被消耗空,因为我们在不断的分配内存空间而不进行回收。除非内存无限大,我们可以任性的分配而不回收,但是事实并非如此。所以,垃圾回收是必须的。
2、哪些内存需要回收?
哪些内存需要回收是垃圾回收机制第一个要考虑的问题,所谓“要回收的垃圾”无非就是那些不可能再被任何途径使用的对象。那么如何找到这些对象?(如何判断一个对象是否可以被回收)
3、如何判断一个对象是否可以被回收
问:垃圾收集器有哪几种?
垃圾收集器底层原理剖析?
垃圾收集器的算法,优化?
(1)引用技术算法
这个算法的实现是,给对象中添加一个引用计数器,每当一个地方引用这个对象时,计数器值+1;当引用失效时,计数器值-1。任何时刻计数值为0的对象就是不可能再被使用的。引用计数为 0 的对象可被回收。正因为循环引用的存在,因此 Java 虚拟机不使用引用计数算法。
package com.baidu.GC;
public class ReferenceCountingGC {
private Object instance = null;
private static final int _1MB = 1024 * 1024;
/** 这个成员属性唯一的作用就是占用一点内存 */
private byte[] bigSize = new byte[2 * _1MB];
public static void main(String[] args) {
ReferenceCountingGC objectA = new ReferenceCountingGC();
ReferenceCountingGC objectB = new ReferenceCountingGC();
objectA.instance = objectB;
objectB.instance = objectA;
objectA = null;
objectB = null;
System.gc();
}
}
二 、JAVA跨平台原理
1、JAVA
Java是可以跨平台的编程语言,那我们首先得知道什么是平台,我们把CPU处理器与操作系统的整体叫平台。
C语言是编译执行的,编译器与平台相关,编译生成的可执行文件与平台相关;
Java是解释执行的,编译为中间码的编译器与平台无关,编译生成的中间码也与平台无关(一次编译,到处运行),中间码再由解释器解释执行,解释器是与平台相关的,也就是不同的平台需要不同的解释器。
在执行的时候,表面上我们调用的是Java.exe,实际上我们在调用java.exe的时候,会去动态调用JVM虚拟机,JVM将字节码文件一行一行的解释成为当前操作系统认识的可执行文件的格式,因此,java是一个“解释型”语言。
Java是编译型的语言,也是解释型的语言,现在明白了,编译型的语言是因为java的你可以说它是编译型的,因为所有的Java代码都是要编译的,.java不经过编译就什么用都没有
而解释型因为java代码编译后不能直接运行,它是解释运行在JVM上的,而JVM的执行方式是把字节码文件一行一行的解释成当前平台认识的可执行文件,所以它是解释运行的,那也就算是解释类型的了。
2、C语言的跨平台原理
那么c语言是不是跨平台的语言呢,实际上我们所说的跨平台,是指编译后的文件是否可以跨平台,从这个角度来讲,c语言不是跨平台的,但是网上有很多人讲c语言是跨平台的语言,这里指的是因为不同平台有对应的编辑器,是源文件跨平台.
3、效率问题
我们回到两个语言跨平台的原理,java把程序先编译成字节码,然后通过对应的JVM进行一句一句的解释执行,而c语言,则直接通过对应平台的解释器翻译成直接可以在对应平台是执行的文件,从这可以看出,c语言的执行效率是快于java的。
三、JAVA的常用DOS命令
(1)控制命令台:
win+R
(2)切换盘符
C: D: E: //大小写都可以
(3)显示详细信息 dir
dir
(4)改变当前目录
cd
(5 ) 当前目录和上一层目录
cd . //当前目录
cd .. //上层目录
(6)清屏
cls
(7)补全命令 TAB
cd s+TAB
(8)创建/删除一个目录
md a // make dir 创建目录
rd a // remove dir 删除目录
(9)复制文件夹
copy demo.txt a\test.txt
(10)删除文件
del 文件名
四、JDK和JRE
JRE(Java Runtime Enviroment) 是 Java 的运行环境。。面向 Java 程序的使用者,而不是开发者。如果你仅下载并安装了 JRE,那么你的系统只能运行 Java 程序。
JDK(Java Development Kit) 又称 J2SDK(Java2 Software Development Kit),是 Java 开发工具包,它提供了 Java 的开发环境(提供了编译器 javac 等工具,用于将 java 文件编译为 class 文件)和运行环境(提 供了 JVM 和 Runtime 辅助包,用于解析 class 文件使其得到运行)。如果你下载并安装了 JDK,那么你不仅可以开发 Java 程序,也同时拥有了运行 Java 程序的平台。JDK 是整个 Java 的核心,包括了 Java 运行环境(JRE),一堆 Java 工具 tools.jar 和 Java 标准类库 (rt.jar)。
五、JAVA基本语法
1、变量
(1)变量的概念
在内存中分配一块地址,用来存储各种不同类型的数据。
(2)变量的类型
int a, b, c; // 声明三个int型整数:a、 b、c
int d = 3, e = 4, f = 5; // 声明三个整数并赋予初值
byte z = 22; // 声明并初始化 z
String s = "runoob"; // 声明并初始化字符串 s
double pi = 3.14159; // 声明了双精度浮点型变量 pi
char x = 'x'; // 声明变量 x 的值是字符 'x'。
变量在声明时候可以没有初始值,但是在使用的时候必须赋予初始值。
JDK10之后,有一种变量声明方式,VAR,但需要赋值,会推断其属于什么类型。
var 变量 = 值
(3)变量的范围
①局部变量
局部变量是在方法、构造函数或块内部声明的变量,它们在声明的方法、构造函数或块执行结束后被销毁,局部变量在声明时需要初始化,否则会导致编译错误
public void exampleMethod() {
int localVar = 10; // 局部变量
// ...
}
②实例变量
实例变量是在类中声明,但在方法、构造函数或块之外,它们属于类的实例,每个类的实例都有自己的副本,如果不明确初始化,实例变量会被赋予默认值(数值类型为0,boolean类型为false,对象引用类型为null)。
public class ExampleClass {
int instanceVar; // 实例变量
}
③静态或类变量
类变量是在类中用 static 关键字声明的变量,它们属于类而不是实例,所有该类的实例共享同一个类变量的值,类变量在类加载时被初始化,而且只初始化一次。
public class ExampleClass {
static int classVar; // 类变量
}
④参数变量
参数是方法或构造函数声明中的变量,用于接收调用该方法或构造函数时传递的值,参数变量的作用域只限于方法内部。
public void exampleMethod(int parameterVar) {
// 参数变量
// ...
}
2、关键字
(1)48个关键字
(2)保留字
goto | const |
(3)特殊直接量
true | false | null |
3、八种基本数据类型
4、数据类型的转换
(1)自动转换
小的数据类型向大的数据类型转换,或者整数类型转换成浮点数类型,都是自动转换的。
byte->short->int->long
public class Main {
public static void main(String[] args) {
// 当文本光标位于高亮显示的文本处时按 Alt+Enter,
// 可查看 IntelliJ IDEA 对于如何修正该问题的建议。
System.out.println("Hello and welcome!");
byte egg = 10;
int x = egg;
System.out.println(x);
}
}
(2)强制转换
大的数据类型转换成小的数据类型则要强制转换。
long->int->short->byte
public class Main {
public static void main(String[] args) {
// 当文本光标位于高亮显示的文本处时按 Alt+Enter,
// 可查看 IntelliJ IDEA 对于如何修正该问题的建议。
System.out.println("Hello and welcome!");
int egg = 10;
byte x = (byte)egg;
System.out.println(x);
}
}
5、基本算数运算
加:+
减:-
乘:×
除法:/
求余(取模):%
注意:
JAVA默认的整数类型是INT
short a = 10;
short b = 20;
short c = (short)(a+b)
注意:
任何的数据类型和字符串使用+运算,+都表示连字符,最后得到的结果都是String类型。
自增自减
① i++ :
i=10;
int j=i++; //先把i的值赋给j,i再+1
// j=10
②i-- :
i=10;
int j=i--; //先把i的值赋给j,i再-1
// j=10
③++i :
i=10;
int j=i++; //i先+1再把值赋给j
// j=11
④--i :
i=10;
int j=i--; //i先-1再把值赋给j
// j=9
public class Ari {
public static void main(String[] args) {
int i=10;
int j=i++; //j=10 i=11
int m=i+++j; //m=21 i=12 j=10
int n=j--+m; //n=31,i=12,j=9,m=21
System.out.println(i);
System.out.println(j);
System.out.println(m);
System.out.println(n);
}
}
6、关系运算符
< > == <= >= !=
import java.util.Scanner;
public class rel {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
System.out.println("请输入两个数字比较:");
int x=scanner.nextInt();
int y=scanner.nextInt();
boolean b=x>y;
System.out.println(x+"是否大于"+y+":"+b);
}
}
7、逻辑运算符
与运算 A&B :同时为真,则结果为真;
或运算 A|B :其中一个为真,则结果为真;
非运算 !A:A必须是boolean类型;
短路与运算 A&&B:和与运算的规则相同,但左侧表达式为False,则直接返回结果为False;如果左侧表达式为True,则右侧运算后返回结果;
短路或运算 a||B:和或运算的规则相同,但如果左侧表达式为True,则右侧不进行运算,直接返回True;如果左侧为False,则右侧计算后再返回结果;
异或运算 A^B:相同为False,不同为True。
注意:
如果要求右侧表达式,不管在什么情况下,都要计算到,则不能用短路。
8、按位运算符(效率高)
首先转换为二进制
按位与:
按位或 :
按位异或
按位取反:
9、移位运算符(效率高)
①有符号位
左移位运算 y<<2:整体将二进制位向左侧移动移位,右侧补0,左移动1位,相当于乘2;(符号不影响)
右移位运算:使用>>符号表示,整体将二进制向右移位,左侧补0,右移动1位,相当于除以2。(符号不影响)
如果移动的位数超过所能表述的长度,则采用求余的方式计算;
如:如果移动32位时候,32%32=0;
如果移动33位的时候,33%32=1.
②无符号位
- 无符号右移位运算:用>>>符号,不考虑正负数的问题;
- 正数移动和右移位相同。
- 负数移动不考虑最左侧负号的问题,意义不大。
10、赋值运算符
= :将右侧的值赋值给左侧变量。
+= :
-= :
……
<<= : 在变量自身上作左移运算 x<<=2
>>= : 在变量自身上作右移运算 x>>=2
>>>=: 在变量自身上做无符号右移运算 x>>>=2
……
11、条件运算符(三元运算符)
x?y:z
表达式1?表达式2:表达式3
x必须位boolean类型的值,如果x为True,则整个表达式取值为y,否则为z。
注意:
不允许 表达式1?表达式2:表达式3 单独存在。
int x=10;
int y=5;
int max=x>y?x:y;
12、优先级
13、从键盘接收数据
导入工具包
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
System.out.println("请输入第一个数字");
double x=scanner.nextDouble();
System.out.println("请输入第二个数字");
double y=scanner.nextDouble();
System.out.println("输出结果");
double z=x+y;
System.out.println(z);
}
}
14、字符类型
①java虚拟机JVM,定义了boolean,但是没有专门的虚拟指令。
②在JAVA语言中,对boolean值操作时替换成int类型数据,占4字节(32位),且只有一位是有效的。
③布尔类型数组,转成byte数组,数据占1字节(8位)。
15、字符串和转义字符
- String不是基本数据类型,是一种引用类型;
- 使用String来声明;
- 特殊的转义字符。
public class String_test {
public static void main(String[] args){
String x = "你好!\nJava!"; //String是一个类
System.out.println(x);
}
}
16、字面量值和常量
字面量:表达的信息如字面所示,程序源码直接给出的一个值,如整数、浮点数和字符串。
常量:不可变的,字面值常量,定义的常量。
//使用final关键字来修饰,不可以重新被赋值
public class ConstTest {
public static void main(String[] args) {
final double pi=3.141526;
}
}
17、编码风格 (驼峰式编码风格)
类名:
- 1个单词组成,首字母大写,后面全小写,如Student Teacher
- 2个或2个以上单词组成,每个单词首字母大写,其他小写,如TeacherName
变量、包、方法名字:
- 1个单词组成,全小写 a b c name
- 2个或两个单词以上组成,第一个单词全部小写,后面每个单词首字母大写
- studentName studentFirstNanme
常量:
- 一个单词组成,全部大写,PI
- 2个或2个以上单词组成,全部大写,中间建议使用下划线分隔。USER_NAME
18、程序结构_分包概念
(1)包的概念
包相当于磁盘下面的一个文件夹。
命名:公司互联网地址的方向写法。如:www.itszb.com,则命名为
|--com.itszb.项目名.模块名
|----java类
在程序中,会出现打包语句:
//package必须在最上边的代码
package.com.coder.xxxx
(2)选择结构
注意:
if...if....
if...else...
这两个是不同的,要注意易错 。
① i f_else
package com.coder.if_test;
import java.util.Scanner;
public class if_Demo {
public static void main(String[] args) {
//从键盘输入一个整数,判断其是否是偶数
Scanner scanner=new Scanner(System.in);
System.out.println("请输入你想要判断的数字:");
int x=scanner.nextInt();
if (x%2==0) {
System.out.println(x+"是偶数!");
}else{
System.out.println(x+"不是偶数!");
}
}
}
猜硬币正反面游戏
package com.coder.if_test;
import java.util.Scanner;
public class if_Else {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
//猜硬币的正反面
double x=(int)(2*Math.random()); //random 0-1之间的小数
System.out.println("请猜正反面(0:反面 1:正面):");
int y=scanner.nextInt();
if (x==y){
System.out.println("恭喜你正确了");
}else{
System.out.println("很遗憾你错误了");
}
if (x==1) {
System.out.println("硬币是正面");
}else{
System.out.println("硬币是反面");
}
}
}
② i f_elseif_else
血型判断
package com.coder.if_test;
import java.util.Scanner;
public class if_Elseif_If {
public static void main(String[] args) {
Scanner scaner=new Scanner(System.in);
System.out.println("请输入你的血型(0:A型 1:B型 3:O型 4:AB型):");
int c=scaner.nextInt();
if (c==1) {
System.out.println("你是A型血");
}else if (c==2) {
System.out.println("你是B型血");
}else if (c==3) {
System.out.println("你是O型血");
}else if (c==4) {
System.out.println("你是ab型血");
} else {
System.out.println("输入错误!");
}
}
}
天气判断
package com.coder.if_test;
import java.util.Scanner;
public class if_Elseif_Demo {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
System.out.println("请你输入您的出生年份");
int month=scanner.nextInt();
if (month==12 || month==1 || month==2) {
System.out.println("冬天出生!");
}else if(month>=3 && month<=5){
System.out.println("春天出生!");
}else if(month>=6 && month<=8){
System.out.println("夏天出生!");
}else if(month>=9 && month<=11){
System.out.println("夏天出生!");
} else {
System.out.println("月份输入错误!");
}
}
}
条件分支嵌套
比较大小
package com.coder.nested;
import java.util.Scanner;
public class if_Nested {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入三个数字比较大小!");
int a = scanner.nextInt();
int b = scanner.nextInt();
int c = scanner.nextInt();
if (a > b) {
if (a > c) {
System.out.println(a + "最大");
} else {
System.out.println(c + "最大");
}
} else {
if (b > c) {
System.out.println(b + "最大");
} else {
System.out.println(c + "最大");
}
}
}
}
石头剪刀布游戏
package com.coder.nested;
import java.util.Scanner;
public class Game {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请出拳(0:石头 1:剪刀 2:布):");
int x = scanner.nextInt();
int y = (int)(3*Math.random());
if (y==0) {
System.out.println("系统出:石头");
if (x==0) {
System.out.println("平局!");
} else if (x==1) {
System.out.println("你输了");
} else if (x==2) {
System.out.println("你赢了");
} else {
System.out.println("你出的不对!");
}
} else if (y==1) {
System.out.println("系统出:剪刀");
if (x==0) {
System.out.println("你赢了");
} else if (x==1) {
System.out.println("平局");
} else if (x==2) {
System.out.println("你输了");
} else {
System.out.println("你出的不对!");
}
} else if (y==2) {
System.out.println("系统出:布");
if (x==0) {
System.out.println("你输了");
} else if (x==1) {
System.out.println("你赢了");
} else if (x==2) {
System.out.println("平局");
} else {
System.out.println("你出的不对!");
}
}
}
}
③switch分支
switch(变量X) X的数据类型支持:byte,short,int,char,String,enum枚举。
前面四个数据类型是老版本支持的。
package com.coder.Switch_Demo;
import java.util.Scanner;
public class Demo1 {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int x= scanner.nextInt();
switch (x) {
case 1:
System.out.println("走1号路线");
break;
case 2:
System.out.println("走2号路线");
break;
case 3:
System.out.println("走3号路线");
break;
default:
System.out.println("另寻他路");
break;
}
System.out.println("可以走出来!");
}
}
也可以简洁写月份
package com.coder.Switch_Demo;
import java.util.Scanner;
public class Bithday {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
System.out.println("Please enter your month of birth");
int x=scanner.nextInt();
switch (x) {
case 12:
case 1:
case 2:
System.out.println("winter");
break;
case 3:
case 4:
case 5:
System.out.println("spring");
break;
case 6:
case 7:
case 8:
System.out.println("summer");
break;
case 9:
case 10:
case 11:
System.out.println("autumn");
break;
default:
System.out.println("Please enter the right month of birth!");
}
}
}
计算器
package com.coder.Switch_Demo;
/*
@author JingPeng
* @project Java Project
* @package_name PACKAGE_NAME
* @data 2024/6/4
*/
import java.util.Scanner;
public class Calculator {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
System.out.println("计算器!");
System.out.println("please enter the first number:");
int x=scanner.nextInt();
System.out.println("please enter the later number:");
int y=scanner.nextInt();
System.out.println("Please enter an operator:");
String op=scanner.next();
String results="";
switch (op){
case "+":
results=(x+"+"+y+"="+(x+y));
break;
case "-":
results=(x+"-"+y+"="+(x-y));
break;
case "*":
results=(x+"*"+y+"="+(x*y));
break;
case "/":
if (y!=0){
results=(x+"/"+y+"="+(x/y));
}else {
results="The divisor cannot be 0!";
}
break;
default:
System.out.println("Please enter the right operator!");
break;
}
System.out.println(results);
}
}
④while循环(打怪)
package com.coder.While_Test;
public class game1 {
public static void main(String[] args) {
// 打怪游戏 玩家300血量,怪物500血量
// 回合制游戏, 玩家攻击力为5-8之间,怪物的攻击力3-5之间
// 直到有一方血量小于等于0,游戏结束
int i=0;
int p=300;
int q=500;
while(true){
i++;
System.out.println("-------------------------------------------------");
System.out.println("第"+i+"回合!");
int x=(int)(Math.random()*(8-5)+5); //玩家攻击力
int y=(int)(Math.random()*(5-3)+3); //怪物攻击力
//萨满攻击
q=q-x;
System.out.println("萨满攻击暗黑魔王,暗黑魔玩血量-"+x+",攻击力为"+x+",血量变为:"+(q));
if (q<=0){
break;
}
//魔王攻击
p=p-y;
System.out.println("暗黑魔王萨满攻击,玩家血量-"+y+",攻击力为"+y+",血量变为:"+(p));
if (p<=0){
break;
}
}
System.out.println(q<=0?"萨满胜利!":"暗黑魔王胜利!");
}
}
⑤do...while
无论如何,都要先执行一次循环。
猜价格游戏
package com.coder.Do_While;
import java.util.Scanner;
public class game1 {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
//猜数字的游戏
//有一件的商品就,价格是1-100之间的数字,系统会提示大或小
//直到用户猜中
int y=(int)(Math.random()*100+1);
int x;
int i=0; //计数器
do{
System.out.println("-------------------");
System.out.println("请输入价格:");
x=scanner.nextInt();
if (x<y){
System.out.println("猜小了!");
} else if (x>y) {
System.out.println("猜大了");
} else{
System.out.println("正确!商品的价格为"+y+"元!");
break;
}
i++;
} while (true);
if (i<=3) {
System.out.println("你是个天才!");
} else if (i<=7) {
System.out.println("不傻,但也不聪明");
} else {
System.out.println("大笨蛋!");
}
}
}
⑥for循环
逢7过
package com.coder.For_Test;
import java.util.Scanner;
public class test1 {
public static void main(String[] args) {
// 100内的数字逢7过
Scanner scanner=new Scanner(System.in);
// 第一个人键盘输出1-10之间的数,表明开始。
int x=scanner.nextInt();
//控制第一个数必须是1-10之间
while (x <= 0 || x > 10) {
System.out.println("请重新输入:");
x = scanner.nextInt();
}
if (x==7) {
System.out.println("过");
x++;
}
for (;x<=100;x++){
if (x%7==0 || x/10==7 || x%10==7){
System.out.println("过");
}else {
System.out.println(x);
}
}
}
}
快速生成for循环的方式
fori
for (int i = 0; i < ; i++) {
}
100.fori //正向循环
for (int i = 0; i < 100; i++) {
}
100.forr //反向循环
for (int i = 100; i > 0; i--) {
}
for循环变量的初始,最好在for循环内声明,遵循迪米特法则
// 迪米特法则:don‘t talk to stranger
// 最少知识原则:耦合度越低,程序越容易扩展,设计越合理
// 高内聚,低耦合
⑦循环嵌套解决搬砖问题
假设有36块砖,由36个人搬走,男人一次搬4块转,女人一次搬3块砖,2个小孩抬一块砖。
男:x人
女:y:人
小孩:z个
4x+3y+0.5z=36
x+y+z=36
package com.coder.For_Test;
public class Ban_Zhuan {
public static void main(String[] args) {
for (int x = 1; x <= 9; x++) {
for (int y = 1; y <=12; y++) {
for (int z = 2; z <= 36-x-y; z+=2) {
if((4*x+3*y+0.5*z)==36 && (x+y+z==36)){
System.out.println("男人:"+x);
System.out.println("女人:"+y);
System.out.println("小孩:"+z);
}
}
}
}
}
}