本文分为上下两篇:上篇地址
Java学习路线、快速复习路线(上)-详解
1.包装类
- 将基本数据类型封装成对象,这样可以在对象中定义更多的方法 *** 作该数据。
- 基本数据类型:byte、short、int、long、float、double、char、boolean。
- 对应的包装类:Byte、Short、Integer、Long、Float、Double、Character、Boolean。
2.自动拆箱、自动装箱
- 自动拆箱:把包装类类型转换为对应的基本数据类型。
- 自动装箱:把基本数据类型转换为对应的包装类类型
Integer i=100; //自动装箱 i+=100; //i=i+100; i+100自动拆箱; i=i+100;自动装箱。
3.int和String类型的相互转换
- int转String:String.valueOf(int num);
- String转int:
- 方法一:Integer.valueOf(s).intValue();
- 方法二:Integer.parseInt(s);
4.异常
- try catch finally:finally是最终语句执行块,只要JVM没崩,里面的语句肯定执行,所以释放资源语句放在finally语句块中。
5.集合、数组
-
集合和数组都是容器,用来存储数据。数组的长度是不可变的,集合的长度是可变的。数组可以存基本数据类型和引用数据类型。集合只能存引用数据类型,如果要存基本数据类型,需要存对应的包装类。
-
集合类结构:
-
Set:
- Set集合不可以存储重复元素,并且没有索引,使用迭代器进行遍历。
- 可以将元素按照规则进行排序。
- 使用空参构造是使用的自然排序。实现Comparable接口,重写CompareTo方法。
- 使用比较器进行排序。创建TreeSet对象时传递Comparator的实现类对象,重写compare方法。
-
哈希值:
- JDK根据对象的地址或者字符串或者数字算出来的int类型数值,通过hashCode()获取。同一个对象调用此方法返回的哈希值相同,不同对象返回的哈希值不同。重写HashCode方法可以实现让不同对象的HashCode相同。
-
底层存储结构:
- 默认长度16,负载因子0.75。
- 根据哈希值和数组的长度计算应存入的位置。
- 判断当前位置是否为null,如果是null直接存入。如果不为null,则已经存在元素,调用equals方法比较属性值。如果相同,不存储,如果不同,存入数组,老元素挂在新元素下面。
- 默认长度16,负载因子0.75。
- 根据哈希值计算存储位置。
- 如果当前位置为Null,直接存入。如果不为null表示有元素,调用equals比较属性值。如果相同,不存储,如果不同则存入数组,老元素挂在新元素下面。
-
HashSet存储自定义类型元素,为了确保元素唯一,必须重写equals和HashCode方法。
6.IO流
-
绝对路径:完整的路径,从盘符开始。
-
相对路径:先对当前项目的路径。
-
File类:略。
-
字节流:如何判定输入输出?相对于内存是输入就是输入,相对于内存是输出就是输出。
- FileOutputStream:略。
- FileInputStream:略。
- write():略。
- read():一次读取一个字节非常低效。可以一次读取一个数组来提高效率。
-
字节缓冲流(效率相对较高,原因是读取和写入都使用了缓冲数组来进行 *** 作)。
- BufferedOutputStream:略。
- BufferedInputStream:略。
-
字符流:因为字节流 *** 作中文不方便,字符流=字节流+编码表。
- FileReader:略。
- FileWriter:略。如果想提高效率,就一次读一个数组。
-
字符缓冲流(效率相对较高,原因是读取和写入端都使用了缓冲数组来进行 *** 作)
-
无论哪种流 *** 作到最后要释放资源。
-
flush方法:刷新流。
-
close方法:刷新流后,关闭流。
7.多线程
- 并行:同一时刻有多个指令在cpu上同步执行。
- 并发:同一时刻有多个指令在cpu上交替执行。
- 进程:正在运行的程序。
- 线程:进程的一条执行路径。
实现多线程:
-
继承Thread类,重写run方法。
- 创建继承Thread类的对象。
- 调用start方法。
-
run方法和start方法区别:
- run:封装线程内的执行代码,如果直接调用就是普通方法。
- start:启动线程的方法。JVM会自动调用run方法。
-
实现Runnable接口
- 创建一个类实现Runnable接口,重写run方法。
- 创建实现Runnable对象,创建Thread对象,将Runnable对象作为参数传入Tread类的对象构造方法中。
- start。
-
实现Callable接口
- 创建一个类实现Callable接口,重写call方法。如果无法计算结构,会抛出异常。
- 创建实现Callable的对象。
- 创建Future Task对象,将Callable的对象最为参数传入。
- 创建Thread对象。将Future Task作为构造方法的参数。
- start。
- get方法可以获得线程结束后的结果。
-
在Java中,线程使用的是抢占式调度模型,优先级高的线程获取Cpu时间片的能力大一些。
8.线程安全问题
public class sell implements Runnable{ private int ticket=100; @Override public void run(){ while(true){ if(ticket<=0) break; else{ try{ Thread.sleep(100); }catch(InterruptedException e){ e.printStackTrace(); } ticket--; System.out.println("还剩"+ticket); } } } }
如果直接在main方法创建一个买票对象,再创建三个Thread类对象启动线程,会出现重复票和负数票情况。
原因:买票过程中,CPU被抢占。
解决方案:
- 同步代码块
public class sell implements Runnable{ private int ticket=100; private Object obj=new Object(); @Override public void run(){ while(true){ Synchronized(obj){ if(ticket<=0) break; else{ try{ Thread.sleep(100); }catch(InterruptedException e){ e.printStackTrace(); } ticket--; System.out.println("还剩"+ticket); } } } } }
- Lock锁
public class sell implements Runnable{ private int ticket=100; private Object obj=new Object(); private ReentrantLock lock=new ReentrantLock(); @Override public void run(){ while(true){ lock.lock(); if(ticket<=0) break; else{ try{ Thread.sleep(100); ticket--; System.out.println("还剩"+ticket); }catch(InterruptedException e){ e.printStackTrace(); }finally{ lock.unlock(); } } } } }
9.线程状态
- 新建:就是创建出来了就是新建。
- 就绪:被调用了start方法。
- 运行:获取了CPU执行权。
- 阻塞:因某种原因放弃了CPU使用权。
- 死亡:执行结束或者JVM出现问题。
10.线程池
- 概念:就是一个任务容器,先创建一些线程。当容器里有了任务县城被唤醒进行执行,执行后不释放资源等待下一个任务。
- 类别:
- newCatchedThreadPool
- newFixThreadPool
- newSingleThreadPool
- …
- 创建线程池对象的参数:new ThreadPoolExecutor(核心线程数量,最大线程数量,空闲线程最大存活时间,存活时间的单位,阻塞队列,创建线程的方式(线程工厂),任务拒绝策略)
11.volatile关键字:不能保证原子性
- A线程修改共享数据,B线程没有及时获取到最新的值
- 使用volatile可以强制线程每次使用时,都会看一下共享区域最新值。
12.悲观锁、乐观锁
- 悲观锁:每次都从最坏角度看待问题,每次获取数据,都会在 *** 作之前进行上锁。
- 乐观锁:很乐观,不会上锁,修改共享数据时会判断有没有其他线程修改过这个数据。如果修改过,获取最新的值。没有修改过,直接进行 *** 作。基于CAS算法。
13.Hashtable
- HashMap线程不安全。
- Hashtable线程安全,但效率低下,扩容机制也与HashMap不同。
ConcurrentHashMap:线程既安全,效率又比Hashtable高。
JDK1.7原理:
- 默认长度16,负载因子0.75。一旦创建无法扩容。
- 再创建长度为2的小数组,把地址给0索引。
- 插入元素,取哈希得到应存储的地址,判断这个元素对应的索引是否为null。为null,根据0索引处创建的数组再创建一个等长的小数组,把小数组的地址赋值给对应索引(在对应索引上挂一个长度为2的数组)。再根据小数组去哈希值,放在小数组对应位置。如果是空直接添加,不为空需要equals判断属性值,如果key相同则不存,否则老元素挂在新元素下。在插入时如果计算位置在小数组的1索引,此时需要扩容,扩容后再插入(负载因子0.75)。
JDK1.8原理:
- 皮一下,请百度。
14.网络三要素
- IP:互联网协议地址;
- 端口:应用程序在设备中的唯一标识;
- 协议:连接与通信的规则;
15.UDP
- 用户数据报协议。
- UDP面向无连接的通信协议,其速度快,每次最多发送64k,数据不安全,易丢失数据。
UDP通信方式
- 单播:一个发送端对应一个接收端。
- 组播:一个发送端对应多个接收端。
- 广播:一个发送端对应所有接收端(局域网中)。
16.TCP
- 传输控制协议
- TCP协议是面向连接的通信协议。
- 速度慢,数据安全,没有传输大小限制。
- 通过三次握手协议保证跟服务器之间的连通。
- 断开过程通过四次回收协议保证与服务器之间断开。
三次握手
- 客户端向服务器发出链接请求。
- 服务器像客户端返回一个响应。
- 客户端再向服务器发出一个确认信息。
四次挥手
- 客户端向服务器发出取消连接请求。
- 服务器向客户端发出一个响应。
- 服务器将最后的数据处理完毕后再向客户端发出确认取消消息。
- 客户端再次发出确认消息。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)