一、JAVA
JAVA常数默认类型
- 整数型默认为int类型
- 带小数的默认为double类型
== 访问权限控制符==
- 权限从大到小排名: public > protected > default(包访问权限) > private
- public : 随处都可以访问
- protected:同一包和不同包的子类
- default:同一包下
- private:同一个类中
成员变量、类变量、局部变量的区别
- 类变量:被static修饰的变量,被所有类实例共享
- 成员变量:1、定义在类中,整个类中都可以被访问 2、随着对象的建立而建立,随着对象的消失而消失 3、成员变量有默认初始化的值
- 局部变量:1、定义在局部范围内,例如函数内、语句内,只在所属的范围有效 2、存储在栈内存中,随着所属范围的消失而消失 3、没有初始化值
重载/重写
- 重载:同名不同参,返回值和修饰符无关(可以在同一个类或者子类中被重载)
- 重写:同名又同参,返回值相关,修饰符不能更严格(只能在子类中被重写)
final
- final修饰的方法不能被重写,可以被重载
- final不能修饰抽象类
接口
- 接口中方法的默认修饰符是public abstract,不能有方法体
- jdk8之后接口方法的修饰符可以是default和static,但是必须有方法体
线程
- start()是启动动作,线程此时就绪,还需等待cpu的调度
- run()方法才是线程获得cpu的时间,开始执行的点
- 创建线程的两种方法:
- 从Java.lang.Thread 类派生一个新的线程类,重写run()方法
- 实现Runnable()接口,重写Runnable接口中的run()方法
- 线程执行时有计算时间和等待时间,其比值和cpu利用率直接挂钩:
- 线程个数 = cpu 个数cpu利用率(1+w/c)
StringBuilder&StringBuffer
- StringBuilder线程不安全(不能同步访问),StringBuffer线程安全
- StringBuilder速度快,StringBuffer速度慢
- 都是字符串变量,改变时不会产生新的未使用对象
Object类中含有的常见方法
- clone() 创建一个该对象的副本并返回
- toString()返回该对象的字符串表示
- notify()启动此对象监视器上等待的单个线程
- notifyAll()启动此对象监视器上等待的所有线程
- wait()当前线程失去操作权限,进入等待序列
- finalize()当垃圾回收器确定不存在该对象的更多引用时,由对象的垃圾回收器调用此方法
== 集合类==
- set:无序的,不可重复的集合
- List:有序的,可重复的集合
- Map:有映射关系的集合
- Queue:先进先出(FIFO)的队列
HashMap
- key不能为空,value可以为空
JSP的9个内置对象
- pageContext 表示页容器 EL表达式、 标签 、上传
- request 服务器端取得客户端的信息:头信息 、Cookie 、请求参数 ,最大用处在MVC设计模式上
- response 服务器端回应客户端信息:Cookie、重定向
- session 表示每一个用户,用于登录验证上
- application 表示整个服务器,开始于服务器的启动,结束于服务器的关闭;实现了用户间的数据共享,可存放全局变量,是ServletContext类的实现
- config 取得初始化参数,初始化参数在web.xml文件中配置
- exception 表示的是错误页的处理操作
- page 如同this一样,代表整个jsp页面自身
- out 输出 ,但是尽量使用表达式输出
== 反射==
常见注解功能
- @Override:指明被注解的方法需要覆写超类中的方法
- @Deprecated:可以修饰类,方法,变量,表示注解的类,方法,变量不建议使用
- @SuppressWarning:抑制编译器编译时产生警告
JAVA并发编程的三个概念
- 原子性:即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行
- 可见性:多个线程访问一个变量,当一个线程改变这个变量,其他线程能够立刻看到(当一个共享变量被volatile修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,它会去内存中读取新值)
- 有序性:程序执行的顺序按照代码先后顺序执行(可以通过synchronized和Lock来保证有序性,很显然,synchronized和Lock保证每个时刻是有一个线程执行同步代码,相当于是让线程顺序执行同步代码,自然就保证了有序性)
满足死锁的四个条件
- 互斥条件
- 等待与保持条件
- 不可侵占条件
- 环路等待条件
二、算法
== 排序==
-
快排
-
归并排序
- 其中,nums是原数组,tmp是复制数组
public int mergeSort( int left, int right){ if(left >= right){ return 0; } int l = left; int r = right; int m = l + (r - l)/2; int res = mergeSort(l, m) + mergeSort( m + 1, r); int i = l; int j = m + 1; for (int k = l; k <= r; k++) tmp[k] = nums[k]; for(int k = l ; k <= r ; k ++){ if(i == m+1){ nums[k] = tmp[j++]; }else if(j == r + 1 || tmp[i] <= tmp[j]){ nums[k] = tmp[i++]; }else { nums[k] = tmp[j++]; res += m - i + 1; } } return res; }
大根堆
- JAVA实现大根堆代码
public void quickSort(int[] arr , int left , int right){ if(left >= right){ return; } int l = left; int r = right; int temp = arr[left]; while(l < r){ while(l < r && arr[r] >= temp ) r--; while(l < r && arr[l] <= temp ) l++; int templ = arr[l]; arr[l] = arr[r]; arr[r] = templ; } arr[left] = arr[l]; arr[l] = temp; quickSort(arr , left , l-1); quickSort(arr, l+1, right); }
三、数据结构
== String ==
- “” 创建的字符串在公共池中
- new String创建的对象在堆中
- 每次被修改都会产生新的字符串,若需要修改,最好使用StringBuffer或StringBuilder
二叉树
- 满二叉树:一个二叉树的结点要么是叶子节点,要么有两个节点,且节点个数为2^k-1(k是深度)
- 完全二叉树:一个二叉有除最后一层外其余各层达到最大个数,且最后一层所有节点连续集中在最左边
- 平衡二叉树:可以是空树,如果不是,首先是二叉搜索树,其次左子树和右子树的深度之差不超过1,且左子树右子树都是平衡二叉树
== 红黑树==
- 所有节点都是红色或者黑色
- 根节点为黑色
- 所有红色节点的子节点都是黑色
- 叶子节点都为黑色的空节点(NIL)节点
堆
- 本质上是一个完全二叉树
- 任何非叶子节点的值都不大于其左右子节点或不小于其左右子节点,分为大定堆和小顶堆
B树和B+树
Queue
- 队列是一种特殊的线性表,只允许在头部删除元素,尾部插入元素,LinkedList实现了Queue的接口,可以当做Queue使用
- offer和add区别:不成功时offer不会宝异常,而是返回false
- poll和remove的区别:空队列时poll返回null不报异常
- peek和element区别:与上面类似,空队列时peek返回null,不报异常
Set
- Set是可变的,无序的,不可重复的元素的集合
- 查询时间复杂度基本和规模无关,使用hash值作为key
== MAP==
- 有映射关系的集合
- put操作过程
- 判断map是否为空,若为空则进行第一次扩容(resize)
- 利用hash算法计算键值对在数组中的索引
- 若当前位置为空,直接插入数据
- 若索引处有值且键相同,则直接覆盖
- 若索引处有值但键不同,则将数据链到链表末端
- 若链表长度达到8,则将链表转换成红黑树,并将数据插入
- 如果数组元素个数超过threhold,再次进行扩容操作
四、计算机网络
HTTP协议
- 应用层超文本传输协议
- 基于TCP/IP协议
五、SPRING
IOC
- 控制反转(依赖注入),将所有对象上交给第三方容器进行管理,当A对象需要B对象时,IOC容器会自动创建一个对象注入,降低了耦合度,相当于一个粘合剂
- 缺点
- 复杂,比原来多了一道手续,开发者需要学习,增加了学习成本
- 生成对象是通过反射机制,运行效率有一定的损耗
SpringMVC
- 三层架构:表现层,业务层,数据访问层
- MVC(表现层):Controller处理浏览器请求,将响应封装成Model,再交给View视图层渲染成HTML页面输送到前端
- 核心组件:前端控制器 DispatcherServlet
-
Thymeleaf:模板引擎,生成动态的的HTML
启动项目要点
- application文件必须在其余文件的同目录或上级目录
ResponseBody
- 将java对象转换成json格式,写入response的body区
六、设计模式
单例模式
-
单例模式属于创建型模式(创建对象时隐藏对象创建的逻辑,使得在判断给定实例需要创建哪些对象时更加灵活)。
-
单例类特点:
- 单例类只能有一个实例
- 单例类必须自己创建自己的实例
- 单例类必须给所有其他对象提供这一实例
-
单例模式分类:
- 饿汉式
-
普通饿汉式实现代码1:
public class Singleton { private static Singleton singleton = new Singleton(); private Singleton(){ } public static Singleton getInstance(){ return singleton; }
-
普通饿汉式实现代码2:
public class Singleton { private Singleton(){}; private static Singleton singleton; static { singleton = new Singleton(); } public static Singleton getInstance(){ return singleton; } }
-
枚举型实现代码(唯一不会被破坏的单例实现模式):
public enum Singleton { Instance; }
-
- 懒汉式
-
普通懒汉式实现方式:
public class Singleton { private Singleton(){} private static Singleton singleton; public synchronized static Singleton getInstance(){ if(singleton == null){ singleton = new Singleton(); } return singleton; } }
-
双重检查式:
public class Singleton { private Singleton(){} private static volatile= Singleton singleton; public static Singleton getInstance(){ if(singleton == null){ synchronized (Singleton.class){ if(singleton == null){ singleton = new Singleton(); } } } return singleton; } }
-
静态内部类实现:
public class Singleton { private Singleton(){} private static class Singleton1 { private static final Singleton Instance = new Singleton(); } public static Singleton getInstance(){ return Singleton1.Instance; } }
-
- 饿汉式
-
单例模式破坏方式
-
序列化破坏单例模式:
public class Client { public static void main(String[] args) throws Exception { WriteObject2GFile(); Singleton singleton1 =InputObject2Stream(); Singleton singleton2 =InputObject2Stream(); System.out.println(singleton1 ==singleton2); } //创建对象输入流对象 public static Singleton InputObject2Stream() throws Exception{ ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:\\tiger\\JAVA学习笔记\\Pattern\\src\\main\\a.txt")); Singleton singleton = (Singleton) ois.readObject(); ois.close(); return singleton; } public static void WriteObject2GFile() throws Exception{ Singleton singleton = Singleton.getInstance(); ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:\\tiger\\JAVA学习笔记\\Pattern\\src\\main\\a.txt")); oos.writeObject(singleton); oos.close(); }
-
反射破坏单例模式:
public class Reverse { public static void main(String[] args) throws Exception { //获取Singleton的字节码对象 Class clzz = Singleton.class; //获取无参构造器 Constructor cons = clzz.getDeclaredConstructor(); //取消访问检查 cons.setAccessible(true); //创建Single对象 Singleton singleton = (Singleton) cons.newInstance(); Singleton singleton1 = (Singleton) cons.newInstance(); System.out.println(singleton == singleton1); } }
-
-
破坏方案解决:
- 序列化破坏解决:
-
在对象中加入readResolve()方法
public class Singleton implements Serializable { private Singleton(){} private static class Singleton1 { private static final Singleton Instance = new Singleton(); } public static Singleton getInstance(){ return Singleton1.Instance; } //当反序列化时,会自动调用该方法,将该方法的返回值返回 public Object readResolve(){ return Singleton1.Instance; } }
-
- 反射破坏解决:
- 在类的无参构造中加一个判断,如果已经被创建了就不创建了
public class Singleton implements Serializable { private static boolean flag = false; private Singleton(){ synchronized (Singleton.class){ if(flag == true){ throw new RuntimeException("不能创建多个对象"); } flag = true; } } private static class Singleton1 { private static final Singleton Instance = new Singleton(); } public static Singleton getInstance(){ return Singleton1.Instance; } public Object readResolve(){ return Singleton1.Instance; } }
- 在类的无参构造中加一个判断,如果已经被创建了就不创建了
- 序列化破坏解决:
== 工厂模式==
代理模式
七、项目实战
== 一般架构==
- controller:处理浏览器发送的请求@Controller
- Service:业务逻辑@Service
- Dao:访问数据库@Repository
- Config:配置类装配第三方bean@Configuration
- Controller->Service->Dao
- 依赖注入:@AutoWired