JavaSE
① 基础
Java之父是詹姆斯·高斯林;
四大特性:垃圾回收机制,面向对象,跨平台,多线程;
Java是解释型语言;
Java是准动态语言;
Java是强类型语言;
因为JVM跨平台,不同操作系统安装不同的JVM,但是它们都能够识别class文件;
public表示资源是公共的;
class是定义类的关键字,一个源文件中可以定义多个class文件,但是public class只能有一个;
main方法是Java程序的入口;
代码中命名可以使用大小写字母,美元符号,下划线,数字,而且数字不能开头,也不能使用关键字和保留字;
② 数据类型
程序是一堆命令的集合;
数据类型的本质是规定占用内存空间的大小;
引用数据类型:类,数组,接口;
基本数据类型:数值型:整数型:byte,short,int,long;浮点型:float(单浮点32位),double(双浮点 64位);布尔型:boolean(4位 0001是true,0000是false);字符型:char(16位);
低精度转高精度不需要进行强转,可以自动转换;
变量分为局部变量(方法中声明的变量),成员变量(类体中不适应static声明的变量),静态成员变量(类体中使用static声明的变量,有默认值,可以和局部变量同名);
如果静态成员变量和局部变量同名的时候,则该方法中,局部变量的优先级高于静态/成员变量;
运算符优先级:分隔符,一元运算符,算术运算符,移位运算符,关系运算符,逻辑运算符,三目运算符,赋值运算符;
流程控制:顺序结构,分支结构,循环结构;
在case语句中需要有break来防止出现case穿透;
continue是跳过当前次循环,继续下一次;
循环分为for,do-while,while三种循环。
循环三要素:初始值,终止条件和步长;
③ 方法
方法就是一堆代码的集合;
方法的声明:
【修饰符列表】 返回值类型 方法名 (参数列表){方法体}
方法分为静态方法,成员方法和构造方法;
return可以返回方法需要返回的类型,还可以单独用来终止方法;
④ 数组
class文件是个静态概念,保存在硬盘中;
Java运行时的数据区域,我们一般叫JVM内存;
执行JVM命令的时候,会把class文件载入内存;
内存分为五个区域:程序计数器,方法区/静态区/静态代码段,栈内存(虚拟机内存),本地方法栈,堆内存;
程序的执行是在栈中执行,其他内存就是存储数据,方法调用就是压栈,方法执行结束就是弹栈;
递归一般用于树状结构,用于遍历查询等操作;
数组可以看作是多个相同数据类型的存储容器,是有序可重复的;
数组的声明:
int[] arr = {1,2};
int[] arr1 = new int[1];
arr1[0] = 0;
int[] arr2 = new int[]{1,2};
length()方法是求数组的长度,以1为开始点;
⑤ 面向对象
面向对象是把数据和方法组织为一个整体看待;
构造器:创建对象,初始化成员变量;
从代码的角度看,new的实例化某一个类的实例,用来保存特有的数据;
类是我们在思想上对某个东西,或者某一类东西的唯一标识;
new会在堆内存空间创建对象空间,并把类中的成员属性复制进去;
根据需求对构造方法进行重载;方法名相同,但是参数的个数或者种类不同;
static是修饰符,区别静态和成员属性;
static定义的变量是共享的;
构造方法名字和类名要相同;
每个对象中,保存当前内存地址的一个引用类型变量,相当于当前对象自己;
this,super不能出现在静态环境中,因为静态环境中没有this这个概念;
创建对象之后立刻执行,创建一次对象,执行一次;
封装就是把对象所有组成部分组合在一起,使用权限修饰符将数据隐藏起来,控制用户对数据的不合理操作;
import语句引入当前类需要的其他包中的类;
如果一个类没有显式继承几个父类的话,默认继承Object;
私有无法被继承,可以通过getter/setter对私有属性进行操作;
Class 子类名 extends 父类名{}
覆写:子类和父类有相同的成员方法(方法名,参数,返回值一样);
覆写出现必须存在继承关系;方法名,参数列表,返回值必须相同;不能有更低的访问权限;不能有更宽泛的异常;
继承最基本的作用:代码重用;
继承最重要的功能:代码覆写;
final是修饰符,表示最终的,不能更改;不能被继承;修饰的成员方法不能被覆写;修饰的变量没有默认值,必须显式赋值,生命周期中不能更改;
多态就是父类引用指向子类对象;
instanceof判断某个对象是否由某个类实例化而来;
Object是java提供的根类,所有类都要直接或者间接继承Object;
使用Interface来定义接口;
Java1.8之前,接口中只有抽象方法和常量,但是public,static,final,abstract等可以省略;
1.8开始,可以有静态,接口也可以有default(可以解决普通类中的成员方法);
接口和接口是多继承,中间用逗号隔开;
一个普通类实现一个接口,需要实现所有的抽象方法;
类关系:继承,实现,依赖,关联,聚合;
在编码实现中,程序员发现有很多编码方式经常被用到,所以总结出来,形成固定写法,一般表示最佳实践,就是设计模式;
单例模式:让某个类只能被实例化一次,一般这个实例化对象由这个类去创建,然后提供一个公共的获取唯一对象的一个接口;
工厂模式:把创建语句封装到工厂类中,提供一个获取对象的方法即可;
⑥ API
String,StringBuilder,StringBuffer都是在java.lang下,所以不需要导包;
String是字符串类,底层是一个char数组;
StringBuffer和StringBuilder是可变的字符串缓冲区,适合用来进行拼接操作;
StringBuffer是线程安全的,多线程的情况下,是不会出现问题的;StringBuilder则是非线程安全的,多线程的情况下,可能出现问题;
int的包装类是Integer,char的包装类是Character,其他基本数据类型的包装类都是首字母大写;
异常是错误的一种说法,导致异常可能的情况有:用户输入非法数据;文件不存在;网络中断;内存溢出;
try…catch 解决异常,一般用在客户端;
throws 抛出异常,一般在服务端,提醒调用处;
throw 异常源,创建一个异常;
finally必须执行的语句块,跟在try或者是try…catch后面;
Throwable是异常类的根类,它的直系子类有Exception和Error;
自定义异常:
继承一个已有的异常类,判断是运行时异常还是编译的异常,如果是运行异常继承RunTimeException,如果是编译则继承Exception;
公共的无参构造; 有参数构造(String 错误信息);
⑦ 集合
在java中集合是存储和操纵元素不固定的一组数据;
Java集合类主要有两个接口派生,Collection和Map;
Collection是list接口和set接口的父接口,它里面的方法在list和set中都可以使用;
ArrayList:底层是一个Object[]数组,随机查询效率高,随机删除效率低;
LinkedList:底层是双向链表,随即查询效率低,随机删除效率高;
TreeSet底层是红黑树(保证元素按照某种顺序排序);HashSet底层是数列;
泛型是类型检查,在编译阶段检查类型是否匹配;
迭代器是一种模式,也可以叫它光标,它可以使序列类型的数据遍历行为和遍历对象分离;
生成迭代器:Iterator it=集合对象.iterator();
迭代器创建之后,集合不能进行添加和删除,如果进行则需要重新创建迭代器;
map的特性是无序,key不可以重复,但是value可以重复,保存键值对映射关系,通过key可以找到对应的value;
在map中有一种特殊的map叫Properties,它的键和值都强制指定位String类型;
⑧ 流
流是一组有顺序,有起点,有终点的字节集合,是对数据传输的总称和抽象;
按照流向可以分为输入流和输出流;
按照处理数据类型的不同可以分为字节流和字符流;
按照功能不同:分为节点流(直接操作数据)和处理流(对其它流进行处理);
OutputStreamWriter 字节输出流变成字符输出流;
InputStreamReader 字节输入流变成字符输入流;
BufferedInputStream 字节文件输入流;
BufferedOutputStream 字节文件输出流;
BufferedReader 字符文件输入流;
BufferedWriter 字符文件输出流;
缓冲流本身属于处理流,需要传入对应的流链接;
PrintStream,字符打印流PrintWriter;
数据流分为DataInputStream和DataOutputStream,分别套接在InputStream和OutputStream子类的流上。
数据流输入和输出的顺序必须是一致的;
对象流是用来存储和读取基本类型数据或对象的处理流;
用ObjectOutputStream类保存基本数据类型或者对象的机制;
用ObjectInputStream类读取基本数据类型或者对象的机制;
两者不能序列化被static和transient修饰的成员变量。
创建序列化的四种方式:new;反射机制;反序列化;序列化;
序列化的对象必须实现Serializable接口;
在序列化中,一般我们会单独指定一个UID来保证版本一致;
transient修饰符修饰,可以把没有必要序列化的变量不进行序列化操作;
File类:文件和文件目录路径的抽象表示,与平台无关;
线程:进程可以细分为线程,是一个程序内部的一条执行路径,若一个进程同时间并行执行多个线程,就是支持多线程的;
线程的生命周期:新建,就绪,允许,阻塞,死亡;
多线程能够提高应用程序的响应,增强用户的体验,提高cpu的利用率,改善程序结构,将长而且复杂的进程分为多个线程,独立运行,利于理解和修改;
线程的创建方式有两种:创建类继承Thread类,覆写run方法,启动线程用的是start方法;实现Runnable接口,覆写run方法,启动线程,调用Thread的start方法;
为了防止两个任务访问相同的资源导致冲突,需要在资源被一个任务访问的时候加上锁;
比起synchronized,lock锁是显式锁,需要手动开启关闭;
lock只有代码块锁,没有方法锁;
当没有线程执行的时候,JVM就会退出,守护线程会随之退出;
Thread中提供了setDaemon方法,可以设置某个线程为守护线程;
⑨ 网络编程
如何准确的定位网络上的一台或多台主机,定位主机上的特定的应用?
IP地址是计算机上的唯一标识,ip地址分类方式:公网地址和私有化地址;
端口号:是正在计算机上运行的进程;
端口号与IP地址的组合得出一个网络套接字,Socket;
网络通信其实就是socket之间的通信,socket允许程序把网络链接当成一个流,数据在两个socket间通过IO传输;
socket工作过程包括四个基本步骤:
创建socket,打开链接到socket的输入输出流,按照一定的协议对socket就那些读写操作;关闭socket;
DatagramSocekt和DatagramPacket实现了基于UDP协议网络程序;
UDP通信流程:
datagramsocket与datagrampacket;建立发送端,接收端;建立数据包;调用socket的发送接受方法;关闭socket;
正则表达式定义了字符串的模式,它可以用来搜索,编辑和处理文本;
PatternSyntaxException是一个非强制异常类,它表示一个正则表达式中的语法错误;
Pattern用于创建一个正则表达式,也可以说创建一个匹配模式,它的构造方法是私有的,不可以直接创建;
lambda是一个匿名函数,我们可以把lambda表达式理解为一段可以传递的代码;
lambda分为两个部分,左侧指定了lambda表达式需要的参数列表,右侧指定了lambda体,是抽象方法的实现逻辑;
只包含一个抽象方法的接口,称为函数式接口;
当函数式接口方法的第一个参数是需要引用方法的调用者,并且第二个参数是需要引用方法的参数(无参)的时候:ClassName::methodName;
MySQL
目前数据库可以分为关系型数据库和非关系型数据库;
对于关系型数据库来说,数据和列是一一对应的,是存在映射的,是以表作为基本单位;
MySQL是关系型数据库,它的轻量级和开源本质让它成为很多中小型网站的数据库;
数据库中表是存储数据的,里面可以细分为记录,记录又是由字段组成;
每个字段可以分为字段名称,字段数据类型,字段约束,字段长度;
数据查询语言DQL,代表人员select;
数据操作语言DML,代表人员insert,delete,update;
数据定义语言DDL,代表人员create,drop,alter;
事务控制语言TCL,代表人员commit,rollback;
数据控制语言DCl,代表人员grant,revoke;
约束类型:
主键 外键 唯一 非空 自增 默认值 关键字;
primary key
foreign key
unique
not null
auto_increment
default
主键通常用于唯一确定表中一条记录,设置主键的字段不能为NULL,而且不能重复;
创建表完成后,通过alter添加主键约束:
如果主键的值用户输入,很可能会导致输入一致不成功,于是自增出现,自增的字段必须是有主键约束的;
外键,它是关联完整性中的一种约束,它可以限定两张有外键关系的表中,一张表中的字段数据需要参考另外一张表中主键值;
唯一约束是指table的列或者列组合不能重复,保证数据唯一性,唯一约束不允许有null出现;
MySQL中没有==,只用=,其实也是数据库里面赋值语句是insert又不是=,然后不等于则是<>,并不是!=;
模糊查询like,其中%匹配任意个数的任意字符,_匹配单个任意字符;
count(*):总条数;
max(字段名):最大值;
min(字段名):最小值;
avg(字段名):平均值;
sum(字段名):总和;
子查询又叫嵌套查询,它通常位于select后,from后.where后;
union和union all都是用于合并查询,前者会自动去除重复项,后者不会;
concat(值,‘拼接符’,值),拼接,多行数据只会拼接一行;
group_concat(值,‘拼接符’,值)拼接,函数将多行压扁成一行;
笛卡尔积,又叫笛卡尔乘积,多表查询中,连接的where限定条件,不能少于表的个数-1,否则会发生笛卡尔积;
对于left join,不管on后面跟什么条件,左表的数据全部查出来,因此想要过滤,必须把条件放在where后面;
对于inner join来说,满足on后面的条件表的数据才能查出来,起到过滤条件,也可以把条件放在where后面;
在最初的JDBC中,我们为了防止异常的出现,重复使用大量的try…catch语句,为了优化代码,我们会采用一些办法,减少代码的重复,提高可用性;
Connection conn = null;
Statement stmt = null;
ResultSet rs = null ;
try {
// 1 加载驱动
Class.forName("com.mysql.jdbc.Driver");
// 2 创建数据库连接对象
// 导包使用的都是java.sql的
conn = DriverManager.getConnection(
"jdbc:mysql://127.0.0.1:3306/_06_", "root", "root");
// 3 创建语句传输对象
String sql = "select * from test_jdbc";
stmt = conn.createStatement();
// 4 接收数据库结果集
rs = stmt.executeQuery(sql);
while (rs.next()) {
// 在循环遍历中,把数据取出来
System.out.print(rs.getInt("id") + " ");
System.out.print(rs.getString("name") + " ");
System.out.println(rs.getDouble("money")+" ");
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
if (rs != null) {
rs.close();
}
if (stmt != null) {
stmt.close();
}
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
一般在JDBC中,我们在进行添加和更改的时候,不会使用Statement而是使用PreparedStatement,因为使用前者可能出现SQL注入的风险;
如果想在一次任务中执行多条语句,就需要用到Batch语句;
Transaction是事务机制管理,默认情况,执行一条SQL语句,就会保存一致,但是如果我需要有三条数据同时成功或者失败,就需要开启事务机制了,如果发生错误,就会回滚到没有操作前;
数据库连接池:达到资源复用的效果,提高了对数据库操作的性能和系统响应;
public class BasicDataSourceUtil {
private BasicDataSource bds;
private static BasicDataSourceUtil bdsu;
/**
* 把初始化数据库链接的代码,放到了 单例模式的构造方法中
*
* 因为当前类是单例的,所以构造方法只能被执行一次,那么链接池对象也就成了单例
*/
private BasicDataSourceUtil() {
bds = new BasicDataSource();
Properties properties = PropertiesUtil.getProperties();
bds.setDriverClassName(properties.getProperty("driver"));
bds.setUrl(properties.getProperty("url"));
bds.setUsername(properties.getProperty("username"));
bds.setPassword(properties.getProperty("password"));
}
/**
* 主要为了解决高并发,所以需要线程安全的单例模式
*
* @return
*/
public static BasicDataSourceUtil getInstance() {
if (bdsu == null) {
synchronized (BasicDataSourceUtil.class) {
if (bdsu == null) {
bdsu = new BasicDataSourceUtil();
}
}
}
return bdsu;
}
/**
* 提供一个获取链接对象的方法
*
* @return
*/
public BasicDataSource getBasicDataSource() {
return bds;
}
}