java基础复习知识点个人使用笔记简易整理

java基础复习知识点个人使用笔记简易整理,第1张

java基础复习知识点个人使用笔记简易整理

个人笔记总结,以便复习使用,仅供参考.

JAVA中的“ 大同小异 “知识点总结

文章目录

一.第一章 基础

1.1 java如何实现跨平台1.2 JDK,JRE,JVM的关系 二.第二章 基础语法

2.1 什么是注释,关键字?2.2 标识符的命名规则2.3 java数据类型分为哪几种?2.4 基本数据类型有哪些?2.5 常用运算符有哪些?2.6 && , & , || , |的区别2.7 位运算符了解吗,有哪些?2.8 if和switch的区别,使用场景2.9 while,do while的区别?2.10 什么时候使用while ? 什么时候使用for?2.11 break,continue的用法,return的作用 ? 三.第三章 数组

3.1 说说你对数组的认识?3.2 什么是索引,索引的特点?3.3 数组的优缺点?3.4 数组的使用场景 四.第四章 面向对象

4.1 对面向对象语言的理解?4.2 面向对象语言三大特征?4.3 继承的优点,何时使用继承?4.4 多态的优缺点?4.5 什么是构造方法4.6 什么是方法重写 ,重载,使用场景?4.7 访问权限修饰符有哪些,作用?4.8 java中包的作用?4.9 static关键字的用法?4.10 this,super关键字?4.11 什么是抽象类,接口, 说说区别,以及为什么要使用抽象类,为什么要使用接口?4.12 final关键字作用? 五.第五章 常用类以及API

5.1 什么是基本类型包装类?5.2 Object类中都有哪些方法?5.3 String类定义的字符串特点?5.4 创建字符串对象的方式有几种,有什么区别?5.5 String,StringBuffer,StringBuilder的区别?5.6 String类常用的方法有哪些?5.7 == 和 equals的区别? 六.第六章 异常

6.1 什么是异常6.2 什么是运行时异常,编译期(检查)异常6.3 异常处理try catch finally的作用,使用方式6.4 throw throws区别 七.第七章 集合

7.1 为什么提供不同的集合类7.2 List,Set,Map集合各自的特点7.3 List集合实现类有哪些,各自特点7.4 ArrayList初始容量,扩容机制7.5 HashMap存储数据的特点7.6 HashMap如何保证键不重复7.8 Collection和Collections的区别 八.第八章 IO流

8.1 File类的作用8.2 流可以分为哪些种类8.3 字符流可以读取图片,音频等文件吗?8.5 什么是对象序列化,对象反序列化,什么时候用? 九.第九章线程

9.1 什么是线程,进程, 他们之间的关系9.2 java如何创建线程9.3 线程的状态有哪些9.4 如何让线程从运行状态转换到阻塞状态9.5 线程何时会出现线程安全问题9.6 如何解决线程安全问题9.7 sleep() 和 wait()的区别 十.第10章网络编程

10.1 网络模型 OSI七层模型和TCP/IP四层模型10.2 网络通信基本要素有哪些10.3 TCP,UDP通信协议的区别10.4 解释TCP三次握手,四次挥手


一.第一章 基础

JAVASE基础 一[了解Java语言,Java配置运行环境]


1.1 java如何实现跨平台

Java语言的特点:开源;跨平台性;交互式特性;多线程机制;动态内存管理;面向对象;安全性;
它的跨平台体现在一次编译,到处运行;

运行机制:
创建.java文件(源代码)----->编译器----->.class文件(字节码)------>不同平台的JVM------>翻译------>指令----->平台运行

JVM:(Java Virtual Machine):Java虚拟机
它是用于计算设备的规范,它是虚构出来的计算机通过在实际的计算机上仿真模拟各种计算机功能来实现的,因为有了不同的JVM,所以同一个Java程序在三个不同的 *** 作系统中都可以执行。 即跨平台性,也称为移植性 ,这个实现的前提是不同的JVM.

Java虚拟机可以理解成一个翻译器。对于不同的运行平台,有不同的虚拟机。Java 虚拟机机制屏蔽了底层运行平台的差别,实现“一次编译,随处运行”


1.2 JDK,JRE,JVM的关系

JDK,JRE,JVM三者关系概括如下:
jdk是JAVA程序开发时用的开发工具包,其内部也有JRE运行环境JRE。
JRE是JAVA程序运行时需要的运行环境。
JDK、JRE内部都包含JAVA虚拟机JVM.


JVM:JVM是Java Virtual Machine(Java虚拟机)的缩写,是整个java实现跨平台的最核心的部分,所有的java程序会首先被编译为.class的类文件,这种类文件可以在虚拟机上执行,class并不直接与机器的 *** 作系统相对应,而是经过虚拟机间接与 *** 作系统交互,由虚拟机将程序解释给本地系统执行。


JRE:JRE是java runtime environment(java运行环境)的缩写。仅有JVM还不能让class文件执行,因为在解释class时JVM需要调用解释所需要的类库lib。


JDK:JDK是java development kit(java开发工具包)的缩写。
JDK的安装目录中有6个文件夹:
一个src类库源码压缩包、和其他几个声明文件。真正在运行java时起作用仅有这四个文件夹:bin、include、lib、jre。

JDK包含JRE,而JRE包含JVM。
bin:最主要的是编译器(javac.exe)
include:java和JVM交互用的头文件


二.第二章 基础语法

JavaSE基础 二[注释,关键字,标识符,数据类型]


JavaSE基础三 (java运算符,控制台输入,条件语句,循环介绍)


2.1 什么是注释,关键字?

Java语言有3种方式的注释;

单行注释:/ / 用于单行注释, 快捷键ctrl+/
多行注释 :
文本注释,在IDEA中使用的话;类或方法或属性上打个 public class MyBatisUtils { private static SqlSessionFactory sqlSessionFactory=null; static { Reader reader = null; try { //读取资源配置文件; reader = Resources.getResourceAsReader("mybatis-config.xml"); } catch (IOException e) { e.printStackTrace(); } //获取sqlSessionFactory对象; sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); } //获取sqlSession; public static SqlSession getSqlSession(){ return sqlSessionFactory.openSession(); } }


继承:
由一个类派生出子类,在子类中可以调用到父类的属性/方法;也可以通过自己重写实现父类的方法来扩展新功能;
比如说儿子可以继承使用父亲的东西,但是父亲无法访问儿子的个人物品;

//父类;
class ClassFa  {
    public String faStr = "父亲";
    private void methodFaPri(){
        System.out.println("我是父类定义的私有方法");
    }

    public void methodFa(){
        System.out.println(faStr);
        System.out.println("我是父类定义的public方法");
    }
}

//子类
public class ClassSon extends ClassFa{
    public String sonStr;

    @Override
    public void methodFa() {
        //可调用父类的方法;
        super.methodFa();
        //可访问父类的属性;
        System.out.println("这是我父亲的属性之一:"+faStr);
        //可自己修改具体实现;
        System.out.println("我是子类重写后加的功能");
    }
    
    //子类可以写自己的新方法;
    public void  methodSon(){
        System.out.println("我是子类的新方法");
    }
}

Object类是所有类的基类(父类);类与类之间的继承,接口与接口之间也可继承;Java类中仅有单继承,接口支持多继承;
虽然说类不能多继承,但是由继承的传递性,也可看到类似多继承的效果;A类继承B类,B类继承C类,C类继承D类;那么A类也就是可用到D类的属性和方法;


多态:
在继承/实现关系的基础上,子类重写了父类的方法,而父类的引用指向子类对象,就是多态机制;

比如学习集合知识的时候,通常使用父类List引用指向子类的对象;这就是多态的体现;

public class Demo {
    public static void main(String[] args) {
        List list = new ArrayList<>();
    }
}

比如在学习JavaEE部分的时候;自定义Servlet继承HttpServlet时,重写使用它的doGet()方法,以及doPost方法;

而根据请求实际要调用哪个方法由HttpServlet类的service()判断;


4.3 继承的优点,何时使用继承?

使用继承,可以提高代码的重用性和可扩展性,
若类/接口之间具有属于关系(is a)时使用继承;
比如宠物狗类和猫类在具有一些相似的方法时,可以考虑创建出一个上层的宠物类;定义方法;让猫类和狗类去继承宠物类;


4.4 多态的优缺点?

优点:可提高代码的重用性;

缺点:父类引用无法直接访问子类特有成员


4.5 什么是构造方法

构造方法:与类名相同,且没有返回值,且不需要使用void修饰;

可以对构造方法进行重载;每个类都有构造方法。若没有显式地为类定义构造方法,这个类默认存在一个无参构造方法;若在Java类中定义了一个构造方法后,那个默认的无参构造方法就会失效。构造方法用于创建对象,当然也可以在此过程中为对象初始化赋值.在调用子类构造器之前,会先调用父类构造器,当子类构造器中没有使用"super(参数或无参数)"指定调用父类构造器时,是默认调用父类的无参构造器,如果父类中包含有参构造器,却没有无参构造器,则在子类构造器中一定要使用“super(参数)”指定调用父类的有参构造器,不然就会报错。


4.6 什么是方法重写 ,重载,使用场景?

方法重载:

在同一个类中,方法名称必须相同;参数列表必须不同;方法的返回值可以相同,也可以不相同;与访问权限修饰符无关.使用方法重载可以提高方法的扩展性.

方法重写:

遵循两同两小一大原则在继承关系中,方法名,参数列表,均相同;子类声明的异常小于等于父类的异常类型,子类的访问权限大于等于父类的访问权限;注意子类的返回值类型要小于等于父类的返回值类型

使用场景:重载主要用于在一个类中,某一部分方法的具体实现细节差不多,只是要传递输入不同的参数类型;
比如在经典的String类型中,就有不同的valueOf(...参数列表)方法,就是方法重载的体现;

方法重写:就是比较常用的了,通常建议定义上层接口,然后下至分发不同的实现类,因为在jdk8以后,接口中也可以写非抽象的方法:静态方法和默认方法;子类必须实现接口中的抽象方法,但是静态方法/默认方法可以根据需要进行实现.
比如集合中的Collection接口,它就有较多的实现类/接口,子类可以使用上层父级的方法,或者扩展自己的新方法实现.


4.7 访问权限修饰符有哪些,作用?

方法权限修饰符有四种:public(公共的),private(私有),protected(受保护的),default(默认的);

对于外部类而言,只能有两种控制级别:public与default;


在类,方法,局部变量/成员变量中可使用的一些修饰符(图源:牛客题目讨论区)


4.8 java中包的作用?

Java中使用的包可以避免类重名的问题;可以控制访问权限,可以根据不同的功能来管理类;

一级包,常用于命名项目的类型/公司业务类性(com);二级包,用于命名醒目开发的公司(例如sun);三级包,用于命名项目的名称(例如cms管理系统);四级包,命名醒目的分化模块名称;


4.9 static关键字的用法?

使用static关键字,可以修饰方法,成员变量,代码块,内部类;

被static修饰的成员会伴随类加载而初始化;被static修饰后,就可以被所有对象共享;静态属性在内存中只有一个;由于被static修饰的静态方法会先加载,所以只能在静态方法中访问使用静态属性;


4.10 this,super关键字?

this关键字用于调用本类自己的属性/方法,而super关键字用于调用父类的公共属性/方法;注意this关键字要放在非静态方法中使用;super关键字用于继承关系中;


4.11 什么是抽象类,接口, 说说区别,以及为什么要使用抽象类,为什么要使用接口?

抽象类:
首先来说说抽象方法,抽象方法呢,它只是声明方法,而不进行具体的实现(没有方法体);需要使用abstract关键字修饰;

注意,我们使用的抽象方法不能用private,static,synchronized,native进行修饰,由于抽象方法要被继承,要是能用private(私有权限访问符)修饰的话,它就不能被子类继承使用了;如果说一个方法被static修饰,它就可以用类名直接调用服务方法的具体实现了,但是抽象方法并没有具体的实现;如果一个方法被synchronized修饰;会为方法加锁;但抽象方法没有具体实现;由于native修饰的方法会被交给本地 *** 作系统,若一块出现了;你这是要把实现交到 *** 作系统手里还是实现子类手里呢

被abstract修饰的类就是抽象类;在抽象类中不一定要有抽象方法;但是定义了抽象方法的类必须声明为抽象类;

注意抽象类不能用final关键字修饰,因为被final关键字修饰的类将不能被继承;

接口: 是一个隐式抽象的抽象类;默认被 abstract修饰 的interface 接口;
接口的属性默认使用public 修饰;
接口的方法默认使用public abstract 修饰;
在java8后,接口中支持定义静态方法和默认方法;


4.12 final关键字作用?

final表示最终的;

final关键字修饰类时,该类不可被继承;

final关键字修饰方法时, 该方法不可被重写;

final关键字修饰的变量,作为常量,定义常量时就应赋予初始化值,或在构造方法中进行初始化;
当final修饰方法参数时,不能再方法中更改参数值;


finally 是异常处理时的关键字,常配合try,catch进行异常处理;作为异常处理的出口;
无论是否触发捕获异常,都会执行finally代码块中的内容;
当时学习网络编程链接的时候,就用到了finally代码块来执行关闭方法close(),保证了链接安全关闭;
当时学习初步web开发流程时,刚开始学的时候没用到线程池;然后就需要频繁地打开关闭与数据库的链接,所以就在finally代码块中执行关闭链接的方法;


finalize:垃圾回收时使用的方法;finalize() 方法允许在子类中被重写,用于在对象被回收时进行资源释放。在垃圾回收该对象之前,总会隐式地调用该方法;注意它仅能调用一次;
且finalize()方法的执行时间不是确定的,只有发生GC垃圾回收时,才会触发;

虚拟机中的对象有三种存活状态,可达状态的(可触及的),可复活状态的 ; 不可触及状态的;
其中可达的就是从根结点触发,可以搜索到达的对象;
可复活的:当这个对象进行回收的时候,它在finalize()方法中又被引用了,那么他就复活了;
但是注意若这个对象在回收时,执行finalize()方法的过程中并没有被引用,那么该对象就是不可触及状态;且不会再有机会起死回生了. (finalize()方法仅能执行一次)


五.第五章 常用类以及API

JavaSE基础六----<常用类(1)>【API||基本数据类型包装类||自动拆箱装箱||Object类||String类||StringBuffer类】


5.1 什么是基本类型包装类?

就是8种基本数据类型对应的引用包装数据类型;

本来Object是所有类的超类,但基本数据类型无法联系起来,
那么对这些基本数据类型做出引用类型的包装类,也就能很好地结合对象使用;

Byte,Short,Integer,Long, 这四种类型都默认存在[-128,127]的缓冲区;
Character默认存在[0,127]范围的缓冲区;


5.2 Object类中都有哪些方法?

常见的hashCode()方法,用于计算当前对象的地址哈希值;

getClass()方法,反射时使用;返回当前的运行时对象Class对象;
equals() 方法,用于比较对象的内存地址是否相同;
clone()方法,用于对象克隆;
toString() 方法,用于输出当前类地址信息的字符串;
notify()方法:唤醒一个等待线程;notifyAll()唤醒所有的等待线程;
wait() 方法,让当前线程进入等待状态,注意会释放锁;
finalize() 方法,GC垃圾回收对象时触发,且仅执行一次.


5.3 String类定义的字符串特点?

字符串是由多个字符组成的一串数据(字符序列)的字符串常量,java中所有字符串都是String类的实例;

一旦定义就是不可变的,因为底层存储使用final修饰的char类型数组;
在创建字符串对象时就已经为value[]指定值;


5.4 创建字符串对象的方式有几种,有什么区别?

两种方式:

String str = new String(“str”);

直接在堆中创建对象;

String str = “str”;

首先在栈中创建引用变量,然后在字符串常量池中查找字符串对象,若没有则就在常量池中创建;
第二次使用时,若在常量池中找到了该字符串直接引用即可;


5.5 String,StringBuffer,StringBuilder的区别?

String类型:不可变类型的字符串;底层是final char [ ] value;因为数组一旦创建长度不可变;被final修饰的引用一旦指向某个对象之后,不可在指向其它对象;

StringBuffer类型;StringBuilder可变类型的字符串;底层是char [ ] value;且都是继承自AbstractStringBuilder类;适用于频繁 *** 作字符串的场景;

但是StringBuffer类支持线程安全;

StringBuffer和StringBuilder的初始化容量都是16;

调用数组工具类方法扩容

关于StringBuffer的length() 方法 和capacity()方法


5.6 String类常用的方法有哪些?

char charAt(int index) 用于查询到字符串的指定索引位置的字符;int compareTo(String anotherString) 比较两个字符串的大小;String concat(String str) 将指定的字符串串拼接到当前字符串的后面;boolean contains(CharSequence s)判断是否包含指定的char值boolean startsWith(String prefix)判断当前字符串是否以指定的前缀字符串开头;boolean endsWith(String suffix) 判断当前字符串是否以指定的后缀字符串结尾;boolean equals(Object anObject)判断两个字符串的内容是否相同;byte[] getBytes(String charsetName) 将指定的字符串转换为字节数组表示;int indexOf(String ch) 计算指定的字符第一次出现的索引位置;String toString() 输出字符串;int lastIndexOf(String str)计算指定字符串最后一次出现的位置;String replace(char oldChar, char newChar) 用指定的新字符替换旧字符后,返回替换后的字符串;String toLowerCase()将当前字符串的字母转换为小写字母表示;String toUpperCase() 将当前那字符串的字母转换为大写字母表示;String trim()清除当前字符串前后的空格;static String valueOf(int i)将指定类型的参数转换为字符串类型;String substring(int beginIndex, int endIndex)截取指定区间(左闭右开)的字符串;char[] toCharArray()字符串转换为字符数组;String[] split(String regex)按指定正则分隔字符串为数组;


5.7 == 和 equals的区别?

==

基本类型比较的是数值;

引用类型比较的是两个对象的内存地址;

equals() 方法
若没有重写equals()方法,比较的是两个对象的内存地址是否相同;
若重写equals()方法,则比较的是两个对象的内容;

一般来说,重写equals()方法伴随着重写hashCode()方法;
对于那些需要比较哈希值的场景;
比如说要将这个自定义的对象存入到hashMap中,由于不可重复性,就需要同时重写equals方法和hashCode方法,保障不重复;


六.第六章 异常

JavaSE基础七----<异常>【常见的异常,异常处理机制,自定义异常】


6.1 什么是异常

异常:就是Java语言定义的,程序执行时的不正常状态就是异常;

由Throwable类 下至的两种异常;Error 错误;Exception 异常;

Error错误是虚拟机都无法解决的程序运行错误;虽不可处理,但是可以尽量避免,比如说提前优化内存空间;注意Error错误不能再程序运行过程中被妥善处理,此时系统会记录错误且安全终止,退出当前进程。

Exception 异常是程序本身可以处理的异常;分为运行时异常和检查期异常;


6.2 什么是运行时异常,编译期(检查)异常

运行时异常(RuntimeException),编译期异常(Checked Exception),就是一个是在程序运行时才会出现的异常,一个是在编写程序时就出现的异常;

运行期异常:·比如常见的ArrayIndexOutOfBoundsException数组越界;NullPointerException空指针…

常见的IOException , SQLException就是编译期的异常,所以在使用IO *** 作,或者链接SQL相关时,在调用编写时就会报出错误,要求我们强制进行异常处理.


6.3 异常处理try catch finally的作用,使用方式

一般来说,异常要么不处理:让系统自己抛出;要么就用try+catch+finally直接组合捕获处理异常;
要么用throw在方法中抛出异常对象,或是在方法处throws声明异常

try,catch,finally通常配合使用;
在try{}代码块中捕获异常;在catch{} 代码块中进行异常处理;
无论异常是否被处理,finally{}代码块中的代码都会被执行;若有return返回值时,先执行finally代码块中的语句;注意若在finally代码块出现之前执行了 System.exit() 方法,那么就不会执行finally代码块中的内容;


6.4 throw throws区别

throw用于在异常处理时抛出异常对象;
throws用于在方法名末尾声明异常;也就是说告诉调用处这个方法中有异常;
如果是声明的是运行期异常,在方法调用处可处理,也可不处理;
如果声明的是编译期异常,在方法调用处,要么声明给调用它的上一级;要么try catch处理;

区别:

位置不同,throws作用在方法上,声明的是异常类;而throw作用在方法内,抛出的是异常对象;功能不同;throws用于声明方法在运行过程可能出现的异常,便于调用处可以预先定义不同的处理方式;而throw用于抛出封装异常信息的对象,


七.第七章 集合

JavaSE基础八----<集合(1)>【泛型、集合体系、Collection接口中的方法,可变长度的参数】

JavaSE基础八----<集合(2)>【List接口及其实现类,List接口的迭代】

JavaSE基础八----<集合(3)>【Set接口及其实现类,Set接口的迭代方式】

JavaSE基础八----<集合(4)>【Map接口及其实现类 Collections类】


7.1 为什么提供不同的集合类

刚开始学习Java的时候,接触的第一种容器就是数组了,但是数组由于自身的限制;比如指定长度就不能改变,且一种类型的数组只能存储一种类型的数据…
这样一来就可以考虑是不是该用新的容器了,它的容量可以自扩容;甚至可以存储不同类型的数据;而且具有不同的结构,灵活高效…

那么,这些可以动态增长长度的容器—集合就来了;


7.2 List,Set,Map集合各自的特点

List集合 是重复的,有序的单列集合;三个实现类ArrayList,linkedList,Vector;
Set集合:不可重复的单列集合;适用于存储无序的(元素的添加顺序)、值不相等的元素;这里所说的对象是否相等其实基于对象的HashCode值是否相同。
Map集合:不可重复的双列集合;


7.3 List集合实现类有哪些,各自特点

ArrayList:基于数组实现,查询快、增删慢,线程不安全;在创建时可以不指定数组的长度;默认初始化长度为10,扩容速度为1.5倍;缺点是元素必须连续存储,若想插入元素,移动元素比较麻烦,所以说ArrayList适用于查询和遍历 *** 作多的场景

linkedList:基于双向链表实现,增删快,查询慢,线程不安全。若要进行插入/元素时,仅需改变节点的指向,比较方便;在linkList中还定义了 *** 作链表头/尾部的方法。
void addFirst(E e) 在该列表开头插入指定的元素。
void addLast(E e) 将指定的元素追加到此列表的末尾。
E peekFirst() 检索但不删除此列表的第一个元素,如果此列表为空,则返回 null 。…

Vector:也是基于数组实现,增删慢,查询快,但是线程安全。 默认长度为10;扩容速度为2倍;
在同一时刻仅允许一个线程对Vector进行写 *** 作,保证在多线程环境下的数据稳定,由于需要频繁加锁、释放锁,它的读写效率实际上比ArrayList差一点呢。

它用到的锁粒度过大,是可重入锁,非公平锁,独占锁,


7.4 ArrayList初始容量,扩容机制

ArrayList的初始容量为10;
无参构造方法;在初步创建时,内部其实仅是个空数组;

添加第一个元素后,默认创建容量为10的数组;

当使用有参构造方法时,创建就产生指定长度的数组;


在add()方法中,当元素装满数组后,会进行扩容为原来的1.5倍;

看这个add方法;首先会进行数组长度的检测;这里size+1为检测是否还能存入一个新元素进去;

若目前的预算容量minCapacity比数组的长度还大,就得考虑调用grow()方法进行扩容了;


grow方法

private void grow(int minCapacity) {
        // overflow-conscious code
        //数组的目前长度;
        int oldCapacity = elementData.length;
        //预算扩容1.5倍后的长度
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        //判断传入的(size+1预算minCapacity)的长度是否合适;
        if (newCapacity - minCapacity < 0)
            //若合适则就将数组长度定义为预算的1.5倍长度
            newCapacity = minCapacity;
            //这里还需判断是否大于数组的最大长度定义:private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            //若1.5倍的预算已超出定义的数组最大长度;
            //则根据minCapacity(之前size+1)的长度决定用多少长度的。
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        //采用数组复制方式扩容;将原来的内容复制到新的容量数组;再给数组elementData
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

超出数组最大长度时调用的hugeCapacity方法;

private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }

7.5 HashMap存储数据的特点

HashMap是以数组加链表的形式存储数据,线程不安全;
首先基于键的HashCode值唯一标识数据,且同时基于key的hash值对数据进行存取;所以他可以快速查询数据;key和value是允许为null的;

数组的每个元素都作为一个单项链表,而在链表的每个元素都是一个Entry(包含key,value,hash值以及指向下一元素的next)

默认容量为16,也是可以扩容的,负载因子为0.75,扩容大小为原来的两倍;也就是当容量到达3/4时就开始扩容,

为减少链表在遍历时的开销,在Java8时HahMap的存储结构有了一点小变化;
数据存储方式变为数组+链表+红黑树;当链表的元素超过8个时,HashMap将链表结构转换为红黑树;


7.6 HashMap如何保证键不重复

HashMap中采用了 hashCode()方法与equals()方法双重检查法,保障键不重复;
拉链法存储

当哈希值相同内容不同时,就会产生哈希冲突;


7.8 Collection和Collections的区别

Collection:作为集合接口;提供对集合对象进行基本 *** 作的基本通用方法;

Collections:集合工具类;定义了一些静态方法,不可被实例化;


八.第八章 IO流

JavaSE基础九----<IO流 (1)>【File类】

JavaSE基础九----<IO流 (2)>【流的体系和分类,字节流,字节缓冲流】

JavaSE基础九----<IO流 (3)>【字符流,字符缓冲流】

JavaSE基础九—<IO流 (4)>【print打印流,对象输入输出流,对象序列化,transient关键字】


8.1 File类的作用

File类只能 *** 作文件的属性,而不能 *** 作其中的具体内容数据;
比如说新建文件夹,删除指定文件。


8.2 流可以分为哪些种类

流的分类;按照方向可分为输入流、输出流;
按照数据单位可分 字节流、字符流;
按照功能可分 节点流、缓冲流


8.3 字符流可以读取图片,音频等文件吗?

注意 字节流可以读写二进制文件,主要处理音频、图片、歌曲、字节流,处理单元
为1个字节。

而字符流主要处理字符或字符串,字符流处理单元为1个字符。


8.5 什么是对象序列化,对象反序列化,什么时候用?

对象序列化:将对象转换为字节序列存储文件,该对象需要实现Serializable接口,
对象反序列化就是 读取字节序列存储文件转换为 对象的过程;

比如说需要持久性地将Java对象存储为文件形式,或者

注意:被transient修饰的属性,不会被序列化.
静态属性也不会被序列化.


九.第九章线程

JavaSE基础(十 一 )—<线程(1)>【线程概述,创建线程,以及线程的方法,优先级,状态,用户线程,守护线程】

JavaSE基础(十 一 )–<线程(2)>【线程同步,死锁,Lock锁,线程通信,生产消费问题,新增的线程创建方式】


9.1 什么是线程,进程, 他们之间的关系

首先一个进程就是正在执行中的程序,含有内存和资源以及存放线程,而一个进程又可以细分为一个/多个线程组成;线程是进程的最小执行单元;


9.2 java如何创建线程

创建线程有4种方式;
(1)继承Thread类;首先这个Thread类也是实现了Runnable接口的;
通过继承Thread线程类;重写其中的run方法;然后创建自定义类的对象;调用线程启动方法start();

public class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"自定义的线程执行体。。。");
    }

    public static void main(String[] args) {
        MyThread m1 = new MyThread();
        MyThread m2 = new MyThread();
        m1.start();
        m2.start();
    }
}
//Thread-0自定义的线程执行体。。。
//Thread-1自定义的线程执行体。。。

(2)实现Runnable接口;
由于在Java的规则中,类只能单继承,那么如果当一个类已经继承了一个其他父类的时候,它没办法通过继承Thread类的方式创建线程了,那么可通过实现接口的方式;比如Runnable接口;
创建自定义的线程对象之后,注意还不能直接启动,需要将创建的自定义对象放入到创建的Thread类对象中,然后再使用Thread类的启动方法;

可以看到在Runnable接口中仅有run方法;

public class MyThread2 implements Runnable{

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"正在执行---");
    }

    public static void main(String[] args) {
        MyThread2 m1 = new MyThread2();
        MyThread2 m2 = new MyThread2();

        Thread thread0 = new Thread(m1,"线程1");
        Thread thread1 = new Thread(m2,"线程2");

        thread0.start();
        thread1.start();
    }
}

(3)实现Callable接口;
使用实现Callable的方式,可以获得一个返回值;
比如说需要在主线程中开启多个子线程并发执行任务,那么可以考虑统计返回的结果。
注意实现的Callable接口后,需重写它的call()方法,

//这里会根据指定的Callable接口方式指定返回值的类型;
public class MyThread3 implements Callable {
    private String threadName;

    public MyThread3(String threadName) {
        this.threadName = threadName;
    }

    @Override
    public String call() throws Exception {
        return "当前执行线程为--"+threadName;
    }


    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //创建线程池;
        ExecutorService e = Executors.newFixedThreadPool(10);
        //任务列表;
        List list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Callable callable = new MyThread3(i+" ");
            //提交线程;
            Future future = e.submit(callable);
            System.out.println("当前提交线程"+i);
            list.add(future);
        }
        //关闭线程池;
        e.shutdownNow();
        for (Future future : list) {
            System.out.println("线程执行的返回结果"+future.get().toString());
        }
    }
}
当前提交线程0
当前提交线程1
当前提交线程2
当前提交线程3
当前提交线程4
当前提交线程5
当前提交线程6
当前提交线程7
当前提交线程8
当前提交线程9
线程执行的返回结果当前执行线程为--0 
线程执行的返回结果当前执行线程为--1 
线程执行的返回结果当前执行线程为--2 
线程执行的返回结果当前执行线程为--3 
线程执行的返回结果当前执行线程为--4 
线程执行的返回结果当前执行线程为--5 
线程执行的返回结果当前执行线程为--6 
线程执行的返回结果当前执行线程为--7 
线程执行的返回结果当前执行线程为--8 
线程执行的返回结果当前执行线程为--9 

(4)使用线程池;由于线程的频繁创建–使用–销毁,是比较消耗内存资源的,那么可考虑将线程装入线程池中,使用线程时获取即可;无需销毁线程;

重点知识学习(8.4)–[线程池 , ThreadLocal]


9.3 线程的状态有哪些

线程主要5个状态:
线程新生状态–线程就绪状态–线程运行状态–线程休眠阻塞状态–线程死亡状态;

首先,当前线程被new出来的时候就在新生状态了;
当线程调用start()方法后启动了线程就处于就绪状态,随时等待CPU资源可用;
当线程获得CPU资源的执行权就可以到运行状态了,注意在运行状态的线程:由于调用了yield()方法或者失去CPU资源时会被遣送回就绪状态, 或者由于线程休眠、线程等待、线程阻塞 而进入到阻塞状态;进入阻塞状态的线程在结束阻塞后,就会重新进入到就绪状态,参与抢占CPU资源;
注意,当在运行状态的线程:正常执行结束,或者出现Error错误/Exception异常时,或被执行了线程的强制停止方法stop()时,线程会进入到死亡销毁状态。


9.4 如何让线程从运行状态转换到阻塞状态

一般来说,阻塞状态可分为三种:

等待阻塞:当在运行状态的线程执行了wait()等待父,就会进入到等待任务队列中;同步阻塞:当运行状态的线程尝试获取同步锁时,此时会被JVM放入到锁池中;其他阻塞:运行状态线程执行了线程休眠方法sleep() 【当前线程休眠】/ 线程阻塞方法【当前线程快速执行,其他线程阻塞】/出现IO请求时,线程进入到阻塞状态,直至sleep()休眠时间到期,join()当前线程终止或超时,IO请求处理结束时,线程才回到就绪态;


9.5 线程何时会出现线程安全问题

线程安全问题主要是在多线程情况下,同一时间内多个线程抢占使用同一个资源时产生,也就是多线程并发时出现。


9.6 如何解决线程安全问题

在之前解决的线程安全问题时,主要是加锁,常用Synchronized 隐式加锁,或使用ReentarntLook显示加锁,
Synchronized 是隐式锁,可用于修饰方法或代码块作为同步方法/同步代码块,使用Synchronized 锁住的是当前类的对象/当前类Class对象/指定对象;
Synchronized是悲观锁,可重入锁,非公平锁,独占锁;
悲观锁与乐观锁的区别;乐观锁主要采用CAS(比较交换机制)、不断比较和更新交换数据,但悲观锁会认为线程的每次更新 *** 作都是线程不安全的、需要加锁。
可重入锁:外层方法获取到锁之后,在内层的调用方法中也能获取到这把锁;
非公平锁:线程释放锁资源后,线程们一拥而上获取锁,而不是规矩的排队等待获取锁;
独占式锁:当前的锁被一个线程使用时,其他线程不能来使用。

ReentarntLook作为显示锁,可用来修饰代码块;在使用时需要手动加锁,手动释放锁。是可重入锁,公平锁/非公平锁(可设置), 独占锁。


9.7 sleep() 和 wait()的区别

sleep():是Thread线程类中的方法;使得当前线程进入休眠阻塞状态,不会释放锁;在休眠时间结束后自己回到就绪状态;

wait():是Object基类中的方法,使得当前线程进入等待阻塞状态,会释放当前锁资源,


十.第10章网络编程

JavaSE基础十—<网络编程>【网络编程概述||通讯要素:IP和端口号,网络通信协议||关于InetAddress类||实现TCP通信||实现UDP通信】


10.1 网络模型 OSI七层模型和TCP/IP四层模型

网络模型OSI七层模型

七层模型,主要包括物理层,数据链路层,网络层,传输层,会话层,表示层,应用层。
物理层定义 物理设备标准,主要用于传输比特流;在发送端将0,1码转换为电流强弱传输,到达目标之后再根据电流强弱转换为0,1码,即数据模型转换、模数转换。
数据链路层:主要是对数据包MAC地址解析封装处理,该层数据以帧存储,设备有网卡,网桥,交换机。
网络层:用于对数据包中的IP地址及逆行封装解析处理。数据包存储。设备:交换机,路由器,防火墙。
传输层:定义传输数据的协议和端口号。主要对数据分段、传输、重组。常用协议TCP/UDP。
TCP传输控制协议:传输稳定,数据量小,但是效率低。
UDP用户数据包协议:传输不稳定,数据量大。
会话层:在传输层基础上, 建立网络连接,管理会话资源。设备之间识别可用IP/MAC/主机名。
表示层:对于接受的数据进行解释,解密/加密,压缩/解压缩 处理。将计算机识别内容转换为开发者可识别内容 --》(图片/音频/文字)。
应用层:基于网络构建具体应用于访问网络的服务接口,比如FTP文件上传下载服务,HTTP服务…


TCP/IP四层模型

TCP/IP协议是指整个TCP/IP协议簇;分为网络接口层、网络层、传输层、应用层。

网络接口层:定义主机之间的网络连接协议。
网络层:用于数据的传输、路由、地址解析。保障主机将数据发送到网络上的目标,主使用IP、ARP地址解析协议。
传输层:将发送端–接收端的对等实体基于会话进行通信。定义了端到端的TCP/UDP协议。
应用层:定义具体应用层协议。FTP(文本传输协议),HTTP(超文本传输协议)…


10.2 网络通信基本要素有哪些

网络通信基本要素:IP、端口号、网络通信协议。

IP:可以精准定位到互联网上的机器;
端口号:可用来标识正在计算机上运行的程序。
通信协议:计算机在网络中进行通信时,规定的协议标准制度,例如通信速率、控制方式…


10.3 TCP,UDP通信协议的区别

TCP控制传输协议:面向连接使用,在发送数据前需建立连接。传输速度慢,会将数据包按顺序排列;重量级连接,需进行三次握手、四次挥手。数据连接可靠,用到SYNSYN-ACKACK协议。

UDP用户数据包协议:无需建立连接,传输速度较快,不可靠,无法保障可将数据送达。里面的数据包没有固定的顺序,相互独立。


10.4 解释TCP三次握手,四次挥手

三次握手

首先客户端向服务端发出SYN(同步序号)报文;且进入同步已发送状态;服务端收到后,打开客户端连接,回应SYN报文;以及ACK(确认字符);进入SYN-RECV(同步已接收状态);客户端收到SYN报文后,回应ACK报文,进入连接状态; – 服务器进入连接状态。


四次挥手:

当客户端打出断开请求时,携带FIN(终止标志位)表示当前客户端的数据已经发送好了,需要关闭网络链路 *** 作,请求服务器确认, 然后客户端进入最终等待状态1(FIN-WAIT);服务器收到消息后,又想客户端发出携带 ACK报文确认消息,表示已收到客户端的断开请求。服务器随之到达关闭等待状态(CLOSE-WAIT)/半关闭状态;而客户端收到回复时就会进入到再次的最终等待状态2;服务器关闭连接之前还需要向客户端发出数据,包括终止标志位FIN 和 ACK确认报文;请求客户端确认关闭连接,服务器进入LAST-ACK最终的确认状态;客户端收到FIN消息,发出ACK确认报文,表示会断开连接。注意客户端此时位于TIME-WAITING计时等待状态,设置的超时时间结束后才到关闭状态。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5718329.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-18
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存