今天提前将项目做完了,想起自己的博客于是将这一个月来思成学习笔记整理了一下。时间很快一个多月来将JAVASE学完了。二阶段将要启动,加油少年
一. 学习周期
- javase 三周 java基础(*****)
二阶段:
2. javaee基础 一周 jsp,servlet
---------javaee企业级应用----------
3. springmvc spring mybatis 二周(*****)
4. struts2 spring hibernate 一周
二、java平台体系
- javase
- javaee
- javame
三、 jdk,jre,jvm的关系
jdk java开发工具
开发和运行java程序
jre java运行环境
只运行java程序
jvm java虚拟机
编译,翻译,运行,分配内存
正是因为有jvm的存在,故java才能实现跨平台.
因为在不同平台上,要安装不同平台的jdk,而jdk包含了jvm
,jvm在运行java代码的时候,会翻译成对应平台
能识别的底层代码去运行,所以可以达到一次编写,
到处运行
三者包含关系为:jdk>jre>jvm
四、java程序的运行原理
- 先把.java文件编译为.class字节码文件
- 运行的时候,jvm把.class字节码文件翻译成对应平台
识别的机器码运行
五、java的基本结构
public class 类名 {(注意:public的类名必须必须必须和文件名相同,且规范为帕斯卡命名法)
// java的主方法,入口,程序从这里开始运行
public static void main(String[] zz) {
}
}
一个文件中可以有多个class,但只能有一个public的class
六、java中三种注释
- // 单行注释
- /* 多行注释 */
- /** 文档注释,可导出文档 */
七、 java的原生类有哪些?
- 原生类指的是八个基本数据类型,
即 byte short int long float double char boolean
String不是原生类!!!!!
八、java默认使用的数值类型是什么?
- 整数默认为int
- 浮点数默认为double
九、变量的初始值?
- 局部变量没有初始值,必须手动赋予初始值才能使用
- 全局变量有初始值,原生类的初始值为0,其他为null
十、类型转换
类型转换分自动转换和强制转换,不论何种转换,都需要数据
要彼此能够兼容
1. 自动转换需要满足:大的类型可以接收小的类型
2. 强制转换需要满足:在要转换的前面加上(数据类型)
,强制转换会丢失数据的精度,比如int a = (int)10.9
,a最终存储的结果为10
十一、java和js中的if,循环,switch等,允许不加{},
但不加的时候,只会包含后续第一行代码在其范围内
十二、多个if和多个else if的区别?
多个if会逐个判断,执行了也会判断后续的if
而else if是一个整体,执行了一个,其他
else if不会在判断
十三、java中==的意思?
在原生类中,比较值
除此之外, 比较的是引用(内存地址)
十四、switch的范围
byte short char int enum 1.7 String
十五、java数组和js数组区别
java数组严格区分类型,不能存储非定义类型的数据
比如整型数组中只能保存整型。
java数组的大写也不可变,不会自动扩张。
十六、 线性表
分两种: 顺序(线性)存储和链式(链表)存储
顺序存储的优点是查询效率高,
缺点是在非最后的位置插入和删除效率低
十七、数组是什么类型?
数组是引用数据类型或叫强类型
十八、数组创建的三种方式
int[] arr = new int[3];
int[] arr = {}; 注意:该方式只能和int[]声明定义同时使用
int[] arr = new int[]{} 注意:该方式[]中扩号中不能含有长度
注意:数组的花括号最后元素可以加逗号,不影响数据长度
十九、细粒度、松耦合、高内聚
二十、访问修饰符
- public 所有地方可以访问
- private 本类中才能访问
- default 默认不写,代表同一个包下面的可以用
- protected 未完待续
二十一、
创建对象=实例化对象
对象=实例
实例变量=成员变量
实例变量有默认值,原生类为0,引用类为null
局部变量没有默认值,必须赋予初值
二十二、
override = 重写 = 覆盖
filed=字段=属性
二十三、
java的引用类型,默认输出会调用toString()方法
二十四、
java的引用类型默认都继承自或派生自Object祖先类
继承可以继承父类所有的属性和方法
二十五、
重写是子类重写父类的方法
重载是重载本类的方法,要求方法名相同,参数列表不同,和其他一切无关!!!!!!!!!!!
类
顾客类可以有N个对象
顾客类的对象都会有顾客的属性和顾客的方法
对象
同一类的对象具有相同的属性,但不同的属性值
有共同的行为(比如购物),但行为中的实现不同(比如各自购物的东西不一样)
二十六、构造方法
- 构造方法名称和类名相同,且不能有返回值
- 每一个类在没有手动设置构造方法的时候都有一个默认的public构造方法
- new对象必须要执行构造方法
- 构造方法可以重载,但无法重写.
二十七. final关键字作用
- final修饰属性代表最终的属性,即常量,不可修改,
当修饰的属性为引用类型时,代表引用不可变,但是引用里面的属性可变 - final修饰方法代表最终的方法,不可以重写
- final修饰的类代表最终的类,不可以继承
二十八. static关键字作用
- static修饰的属性为类属性,修饰的方法为类方法
不依赖于实例,只依赖于类,最早加载 - static修饰的属性和方法只有一份
- static修饰属性一般要和final一起使用变为静态常量,
因为static修饰的属性会有共享安全问题,多个实例修改是同一份空间 - 静态方法不能直接调用实例属性和实例方法,因为没有this.
要调用的话,需要先实例化对象.
5.static修饰的属性和方法不易于GC回收,太多容易造成内存溢出
6.static不可以在方法内部修饰属性
二十九. this关键字作用
- this关键字只能使用在实例方法和构造方法中
- this代表当前实例
- this可以访问实例属性,实例方法,和构造方法
- this访问构造方法时,必须在构造方法的第一行
三十. 什么是继承
- java中使用extends关键字继承
- java中的类只能单继承
- 子类继承父类所有属性和方法,但是只能访问有权限的属性和方法
- 父类只提取子类共同的属性和方法
三十一. super关键字
- super代表调用父类实例
- 如果子类没有父类的属性,那么super和this调用的是同一份空间
- 如果子类有的话,super和this获取到的数据不一样,super设置父对象的空间
this设置本身的空间 - 子类如果重写了父类的方法,那么this.method()会调用子类的重写的方法
但是属性不会,因为属性不存在重写.
三十二.抽象类
- 当一个类作为父类使用,本身不需要被实例化的时候,可以设置为
抽象类. - 抽象类不能被实例化
三十三. 抽象方法
- 抽象方法本身没有方法体,也不需要被调用
- 抽象方法必须包含在抽象类中,所以也无法调用,因为没有实例
- 抽象方法的作用是为了设置标准,限制子类必须按这个方法签名去重写方法
- 子类必须重写父类的抽象方法,除非子类又是一个抽象类
- 抽象方法可以实现多态
三十四. 重写
- 发生在子父基础关系中,子类重写父类方法
- 方法名和参数列表必须相同
- 访问权限不能比父类更严格,也就是要比父类更大(大是什么意思?)
- 返回值类型必须相同或者是父类方法返回值的子类
- static方法无法重写
- 声明的异常不能比父类更大
三十五. 异常
try catch 捕获可能发生的异常
throw 强制抛出一个异常
throws 向上声明异常,写在方法的签名后面,意在告诉调用方去处理
Throwable 异常的基类,异常最大的类.有2个子类分别为:Exception,Error
Exception 编码级别的最大异常类,下面分为RuntimeException
和非RuntimeException(或称为检查性异常)
Error 非编码级别的最大错误类,一般硬件或内存不足或编译错误.通过编码很难处理的错误.
RuntimeException 运行时异常,不要求必须处理
检查性异常 必须处理,否则编码将不通过
三十六、集合篇
1.
List,Set继承自Collection接口
ArrayList,LinkedList继承自List接口
HashMap,Hashtable继承自Map接口
HashSet,TreeSet继承自Set接口
ArrayList为线性存储,查询效率快,尾部插入也快
中间插入和删除效率低
LinkedList为双向链表存储,插入删除效率快,非首尾查询效率低
-
Set无序(这里的无序指不按插入顺序排列)不可重复,
TreeSet多了排序功能,前提是需要实现Comparable接口的
compareTo方法编写排序规则 -
HashMap和Hashtable都是使用key和value
键值对的保存方式,通过key查找value.key不可以重复,会覆盖.
value可以重复.
两者区别是 hashmap可以有null的key,线程不安全
hashtable不可以有null的key,线程安全
集合遍历方式有: foreach for iterator lombda表达式
三十七. == equals区别
- 原生类只能使用==比较,比较的是值
- 引用类比较的是引用(地址),equals在不重写的情况下
是继承自Object类的equals方法,它的实现和相同,比较地址 - 重写后,按你重写的方式来比较
- java推荐重写equals方法,也需要重写hashcode方法,
目的是为了保证一个对象如果equals相等,那么它们的
逻辑内存地址也应该相等.反之,只重写equals而不重写hashcode,
会导致在一些地方(HashSet,HashMap)使用,
会发生相同的对象被重复存储
三十八、什么是克隆
- 克隆对象必须实现Cloneable接口
- 克隆是创建一个新的对象
三十九、什么是GC
GC为java中的垃圾回收器,作为java的守护线程在后台运行
,检测没有使用的内存,对其进行释放空间.
但程序员无法保证它何时运行.只能通过System.gc()通知,
但通知了,也不能保证何时执行.
GC回收一个对象的时候,会首先调用它的finalizy方法.
四十、IO
- IO指InputStream和OutputStream,输入输出流
- 输入输出流又细分为字节流(操作文件)和字符流(读取中文)
- 计算机其实只有字节流,字符流乃通过字节流封装出来的
四十一、什么是缓冲区
- 缓冲一定的内存大小,避免频繁访问硬盘,提升性能和效率
- 缓冲区中的内容没有满的时候,需要调用flush将剩余缓存的
空间输出. - 输出流Writer中默认有一个1kb的缓冲区,注意flush或close.
四十二、readline方法
该方法需要读取到一个换行符,才结束,否则一直等待。
如果在等待的时间,客户端断开了连接,那么会抛出一个连接重置异常
四十三、进程和线程的关系
一个进程可以包含多个线程
一个线程单独作为一个单元运行,可执行某种任务
实现线程有三种方法:
- 继承Thread类 直接new 类.start()
- 实现Runnable接口 没有start方法,使用时需要new Thread®.start()嵌套一层
- 使用线程池 有四种,参考四十五
四十四、run和start区别
-
当线程开始运行,会调用run方法.
但是如果程序员手动调用该run方法,那么和普通方法一样 -
start是告诉jvm启动一个新的线程运行run方法.
四十五、线程池有几种?
- CachePool 有就用原来的
没有就创建,创建数量无上限(Integer.MAX_VALUE). - FixedPool 有就用原来的,没有就创建,创建数量固定上限,后续任务等待.
- SinglePool 只创建一个线程来完成任务,后续任务等待.
- ScheduledPool 周期性执行的线程池(类似setInterval)
四十六、线程安全
-
局部变量不存在线程安全问题,因为每个线程进入的方法会有单独的空间
-
加上synchronized关键字同步.
可以同步整个方法.也可以同步部分代码块. -
使用Lock对象(tryLock,lock,unlock方法)
-
使用读写锁,提升性能.可以一起读.但读的时候不能写,
写的时候不能读和写. -
使用本地线程ThreadLocal,为每一个线程保存一份单独的空间
,该方式可以理解为使用空间换时间.
四十七、synchronized
- synchronized可以锁局部代码块
- synchronized写在实例方法上,默认的锁对象为this
当一个对象的实例方法使用了synchronized,那么这个对象的
其他synchronized方法也同样加了this锁.其他线程也同样需要
等待锁释放才能运行这些synchronized方法. - synchronized写在静态方法上,默认的锁对象为该方法的类的字节码
.其他使用该字节码同步锁的方法,需要等待该字节码锁被释放.
四十八、什么是死锁, 怎么解决死锁
—>两个或多个线程直接相互等待彼此释放锁,会造成死锁。
解决:
1、 使用Lock的tryLock, 一段时间获取不到就执行unlock释放
2、 synchronize使用同一个锁对象
3、 使用ThreadLocal
四十九、volatile关键字的作用
- 防止指令的重排序
- 每次获取到是最新的值
- 不能保证线程安全
五十、 线程的方法
-
join 示例:thread1.join
阻塞运行,等待thread1执行完成后,程序继续往下执行 -
stop 过时不推荐,直接停止线程,导致不安全
-
interrupt 设置一个interrupt布尔标志为true,然后线程根据这个标志
可以决定什么时候退出. 如果在线程阻塞的情况下调用了interrupt,那么线程会抛出
一个interruptException并重置interrupt为false -
sleep(ms)阻塞当前线程一段时间,并且不会释放同步块(锁)
-
yield 退让,给OS调用其他同级别线程的机会,自己重新回到就绪状态参与竞选,
可以理解为自动时间的sleep.不会释放锁. -
wait 等待,释放对象锁并且进入等待状态.释放的必须为同步块的锁对象
可以有参数设置ms多久进入就绪状态(一般不推荐,可能导致线程不安.全).
也可以不写参数,那么会一直等待下去,需要其他线程唤醒它才能继续运行 -
notify 随机唤醒一个等待状态的线程.
该方法必须和要唤醒的线程,在同一个锁对象中.
五十一、线程的生命周期和线程状态的转换
- 新建—>就绪(可运行)—>运行—>等待/阻塞–>可运行–>死亡
- 状态转换参考手机图
五十二、java的反射是什么 ?
- reflect反射,
- java程序在运行的过程中可以得到任意一个类的属性和方法
,也可以执行任意一个对象的属性和方法
五十三、反射的方法
- getFiles,getMethods 获取所有public的属性,方法(含父类)
- getDeclareFiles,getDeclareMethods 获取所有当前反射类的所有属性,方法
- getDeclareConstructors 获取所有共有构造器(不含父类,因为构造器不能被继承)
番外篇:
帕斯卡命名法:每个单词的首字母大写,如
MyName, MyGirlFriendName
一般用于class上
驼峰命名法:第一个单词首字母小写,其他单词首字母大写,如
myName, myGirlFriendName
一般用于变量和方法上
什么是C/S程序,B/S程序
Client/Server 客户端/服务器
要客户去安装,更新
Browser/Server 浏览器/服务器
跨所有
三种错误
1.编译错误,编译
出错无法编译class字节码
2.运行出错,编译通过,然后程序在运行的时候报错
3.逻辑错误,编译和程序都正常,但是效果不是预期