计算机网络

TCP/IP模型与OSI模型

​ OSI(Open Systems Interconnection)是国际标准化组织(ISO)在1984年发布的,目的是创建一个标准化的网络通信框架,以便不同厂商的设备可以相互操作。

物理层(Physical Layer):主要用于比特流传输的物理连接,如光纤、网线、无线电波等。

数据链路层(Data Link Layer) :同一个数据链路内的帧传输,对应物理地址(MAC)寻址,错误检测与纠正,如以太网等。

网络层(Network Layer) :负责端到端的通信,主要用于路径选择和逻辑地址(IP)管理。

传输层(Transport Layer) :用于可靠传输,流量控制,错误检测,如TCP, UDP等。

会话层(Session Layer):建立、管理、终止会话,如NetBIOS、RPC等

表示层(Presentation Layer) :用于数据格式转换、加密、解密,如JPEG, MPEG, SSL/TLS等。

应用层(Application Layer):用户交互界面,提供网络服务,如HTTP、FTP等。

数据链路层和网络层

​ 数据链路层负责相邻设备(同一链路)之间的通信,即从电脑和交换机之间、路由器和路由器之间的直接数据传输。

​ 网络层负责端到端的通信(跨多个网络)

可以把数据传输比喻成寄快递

  • 数据链路层 相当于快递员在同一个城市内派送包裹,按照门牌号(MAC 地址)找到收件人。
  • 网络层 相当于快递公司的物流系统,负责决定包裹从上海到北京要经过哪些中转站(路由)。

会话层

协议 功能
RPC(远程过程调用协议) 允许程序在远程计算机上执行某个过程,比如分布式系统。
SQL(结构化查询语言) 通过会话层维护数据库连接。
NetBIOS 用于局域网中的计算机名称解析和会话管理。
SMPP(短消息对等协议) 用于短信传输,比如短信网关的通信。
PPTP(点对点隧道协议) 用于VPN连接,建立加密隧道。

TCP三次握手

(1) 三次握手的过程

  1. 第一次握手:客户端向服务器发送一个SYN (同步序列编号)报文,请求建立连接,客户端进入SYN_SENT 状态。
  2. 第二次握手:服务器收到SYN 报文后,如果同意建立连接,则会发送一个SYN-ACK (同步确认)报文作为响应,同时进入SYN_RCVD(Synchronize Received) 状态。
  3. 第三次握手:客户端收到服务器的SYN-ACK 报文后,会发送一个ACK (确认)报文作为最终响应,之后客户端和服务器都进入ESTABLISHED(建立) 状态,连接建立成功。

(2)为什么需要三次握手

通过三次握手,客户端和服务器都能够确认对方的接收和发送能力。第一次握手确认了客户端到服务器的通道是开放的;第二次握手确认了服务器到客户端的通道是开放的;第三次握手则确认了客户端接收到服务器的确认,从而确保了双方的通道都是可用的。

而如果仅使用两次握手,服务器可能无法确定客户端的接收能力是否正常,比如客户端可能已经关闭了连接,但之前发送的连接请求报文在网络上延迟到达了服务器,服务器就会主动去建立一个连接,但是客户端接收不到,导致资源的浪费。

TCP四次挥手

(1)四次挥手的过程

  1. 第一次挥手:客户端发送一个FIN报文给服务端,表示自己要断开数据传送,报文中会指定一个序列号 (seq=x)。然后,客户端进入FIN-WAIT-1 状态。
  2. 第二次挥手:服务端收到FIN报文后,回复ACK报文给客户端,且把客户端的序列号值+1,作为ACK报文的序列号(seq=x+1)。然后,服务端进入CLOSE-WAIT(seq=x+1)状态,客户端进入FIN-WAIT-2状态。
  3. 第三次挥手:服务端也要断开连接时,发送FIN报文给客户端,且指定一个序列号(seq=y+1),随后服务端进入LAST-ACK状态。
  4. 第四次挥手:客户端收到FIN报文后,发出ACK报文进行应答,并把服务端的序列号值+1作为ACK报文序列号(seq=y+2)。此时客户端进入TIME-WAIT状态。服务端在收到客户端的ACK 报文后进入CLOSE 状态。如果客户端等待2MSL没有收到回复,才关闭连接。

(2)为什么需要四次挥手

TCP是全双工通信,可以双向传输数据。任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。 当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后才会完全关闭 TCP 连接。因此两次挥手可以释放一端到另一端的TCP连接,完全释放连接一共需要四次挥手。

只有通过四次挥手,才可以确保双方都能接收到对方的最后一个数据段的确认,主动关闭方在发送完最后一个ACK后进入TIME-WAIT 状态,这是为了确保被动关闭方接收到最终的ACK ,如果被动关闭方没有接收到,它可以重发FIN 报文,主动关闭方可以再次发送ACK

而如果使用三次挥手,被动关闭方可能在发送最后一个数据段后立即关闭连接,而主动关闭方可能还没有接收到这个数据段的确认。

服务器不等待客户端的ack直接关闭,可能会出现客户端想要继续数据传输的情况

背诵

​ 客户端向服务器发送 fin,服务器收到后返回ack,之后服务器向客户端发送fin,客户端收到后向服务器发送ack后等待一段时间断开连接。

Mysql

sql语言和方言的区别

sql语言:所有的关系型数据库的通用规则(通用性

方言:每一种关系型数据库特有的规则(不具有通用性

sql语句的分类

DDL语句

​ 用来操作

DML语句

​ 用来操作数据增删改,不包括查询

DQL语句

​ 用来操作数据查询

DCL语句(了解)

​ 用来给用户授权 (DBA)

mysql中double类型和decimal类型的区别

float/double(m,d)

存储的近似值

m 表示所有的位数 d 小数的位数

95.5 double(3,1)

3.1415926 double(8,7)

decimal(m,d)

存储的是准确值,和钱相关的只能decimal

95.5 decimal(3,1)

null值参与计算的结果是什么

null值参与四则运算,结果为null

解决方案:使用ifnull函数

1
2
-- 如果comm是NULL,则返回0;如果comm不是NULL,则返回comm的实际值
IFNULL(comm,0)

关系型数据库中,null值参与排序的结果

mysql中,作为最小值

oracle中,作为最大值

null值是否参与聚合函数的计算

null值不参与聚合函数

常见的聚合函数

  1. max(字段名):求最大值

  2. min(字段名):求最小值

  3. sum(字段名):求和

  4. avg(字段名):求平均值

  5. count(字段名):计数

where和having的区别

where:是分组前过滤,后面不能跟聚合函数

having:分组后过滤,后面可以跟聚合函数

数据库中约束的分类有哪些

  1. 非空约束:not null

  2. 唯一约束:unique

  3. 默认约束:default

  4. 主键约束:primary key

  5. 外键约束:foreign key

主键约束和非空且唯一约束的区别

主键约束:一张表只能有一个

非空+唯一约束:一张表可以有多个

一对多关系怎么设置外键

在多的一方建立外键指向一的一方的主键

数据库设计的三大范式

第一范式:每一列都是不可再分的原子数据项

第二范式:消除部分依赖,从而消除冗余数据

第三范式:消除传递依赖

内连接和左外连接的区别

内连接:查询的是两个表公共部分

左外连接:查询的是左表的所有+公共部分

数据库中是否支持全连接

full join

mysql不支持,oracle支持

union all和union的区别

作用:求并集

  1. union all:返回两个集合的所有数据,包含重复值

  2. union:返回两个集合的所有数据,不包含重复值

什么是事务

其实就是我们现实生活中的业务,银行转账业务(张三给李四转500块钱)

在mysql中事务指的是多条增删改语句组成的整体,要么全部执行成功,要么回滚失败。

事务是怎么保证同时成功或者同时失败的

通过事务的三个操作

start transaction:开启事务

​ 会把接下来的操作都作为一个整体,整体里面的每一个增删该语句产生的都是临时值,此时并不会改变数据库中真正的数据。

​ 如果回滚,回滚到start transaction的位置

commit:提交操作

​ 判断执行的过程中,有没有问题,没有问题,则把临时值真正地更新到数据库中

rollback:回滚操作

​ 判断执行的过程中,有没有问题,有问题,则把临时值取消掉

事务的四大特征

事务的四大特性通常被称为 ACID 特性

  1. 原子性(atomicity):把事务当成一个整体,要么同时成功,要么同时失败。
  2. 一致性(consistency):事务执行前后,数据的总和不变。
  3. 隔离性(isolation):多个事务之间,是相互独立的。
  4. 持久性(durability):执行了commit操作的时候,会把数据库更新到硬盘上。

事务的隔离级别及可能出现的问题

​ 多个事务之间,是相互独立的,但是当多个事务操作同一批数据的时候,就会出现问题,我们需要设置不同的隔离级别来解决

可能出现的问题:

脏读

​ 一个事务读取到另外一个事务还没有提交的数据

不可重复读(虚读)

​ 一个事务读取到另外一个事物已经提交的update语句 // 数量不变 ,内容变

幻读

​ 一个事务读取到另外一个事物已经提交的insert语句 // 数量变化

隔离级别:

​ Read Uncommited:读未提交

​ 可能出现脏读、不可重复读(虚读)、幻读

​ Read Commited:读已提交 (oracle数据库的默认隔离级别

​ 可能出现不可重复读(虚读)、幻读

​ Repeatable Read:可重复读 (mysql数据库的默认隔离级别

​ 可能出现幻读

​ Serializable:串行化

​ 没有问题

慢查询语句的作用是什么

使用慢查询语句explain查看DQL是否走了索引

1
2
3
4
5
6
EXPLAIN SELECT * FROM person WHERE NAME = 'test0.6239561854153464';

-- 给person表的name字段添加索引
CREATE INDEX person_name ON person(NAME);
-- 删除person表的name字段的索引
ALTER TABLE person DROP INDEX person_name;

使用模糊查询时是否会导致索引失效

  1. 如果占位符(% _) 在开头,不走索引
  2. 如果占位符(% _) 在末尾,走索引

联合索引走索引的条件是什么

最左前缀原则(最左匹配原则)

索引的底层结构是什么

B+树

B树和B+树的区别

B+树的叶子节点之间有指针相互指向

B+树的非叶子节点中的数据在叶子节点中都冗余了一份

JavaSE

Java的版本分类有哪些

  1. JavaSE:可以用来进行桌面开发(已弃用)

  2. JavaME:用来作为小型设备开发

  3. JavaEE:用来作为大型服务器开发的

JavaSE是其他两种(JavaME和JavaEE)的基础

Java中跨平台的原理是什么

Java通过JVM实现跨平台:针对不同的操作系统,都会有不同版本的虚拟机

JDK、JRE和JVM的区别

JDK

JDK(Java Development Kit):Java开发工具集

特点:可开发、可运行

JRE

JRE(Java Runtime Environment):Java运行环境

特点只能运行、不能开发

JVM

JVM(Java Virtual Machine):Java虚拟机

特点:在不同的操作系统中运行Java代码

面试题:JDK、JRE、JVM三者之间的关系

JDK > JRE > JVM(>号是包含)

Java中的注释有哪几种,分别怎么表示

  1. 单行注释: // 注释的内容

  2. 多行注释: /* 注释内容 */

  3. 文档注释: /* * 注释内容 */

Java中常量的分类

  1. 整数

  2. 浮点数

  3. 布尔

  4. 字符:单引号引起来的,单引号中只有一个字符

  5. 字符串

  6. 空常量:一个特殊的值:null,”null”是字符串

Java中的数据类型有哪些

a++和++a的区别

a++:先赋值,再自增(++在后)

++a:先自增,再赋值(++在前)

为什么要使用Idea

可以把编写代码、编译代码、运行代码等多种功能都综合到一起

方法的分类

  1. 无参无返回值

  2. 无参有返回值

  3. 有参无返回值

  4. 有参有返回值

什么是方法重载

同一个类中的多个方法之间,满足以下条件的构成重载:

  1. 方法名相同

  2. 参数列表不同

  3. 与返回值无关

switch语句中小括号里的表达式可以是哪些数据类型

只能是byte、short、int、char,JDK5以后可以是枚举,JDK7以后可以是String

数组的特点

  1. 数组的长度不能改变

  2. 数组中的元素的类型必须是同一种数据类型(基本类型/引用类型)

  3. 存入数组中的元素,按照存入的顺序排列

数组的动态创建方式和静态创建方式的区别

动态方式:只指定长度,由系统给出初始化值

1
int arr2[] = new int[5];

静态方式:给出初始化值,由系统指定长度

1
int[] arr1 = new int[]{1, 3, 5};

Java中的内存划分

Java的内存区域主要分为以下几个部分:

  1. 程序计数器:和CPU相关。
  2. 本地方法栈:和系统相关。
  3. Java虚拟机栈(栈):方法、局部变量、对象的引用
  4. :所有new出来的东西。
  5. 方法区:字节码文件对象、常量池、静态区。

背诵:方局对,自(字)常静

面向对象和面向过程的区别

面向对象和面向过程是软件分析、设计和开发中解决问题的思想

面向对象和面向过程解决问题的思路不同

  1. 面向对象:我找能做这件事的”对象”帮我去做
  2. 面向过程:强调的是自己”一步一步”去做

什么是类?什么是对象?

类:对某一类事物的抽象表示,是一种分类

对象:是能解决问题的具体存在

类和对象的关系

类是对象的一个分类/模板

学生:张三、李四

学校:南邮、南师

成员变量和局部变量的区别

区别 成员变量 局部变量
类中位置不同 类中方法外 方法内或者方法声明上
内存中位置不同 堆内存 栈内存
生命周期不同 随着对象的存在而存在,随着对象的消失而消失 随着方法的调用而存在,随着方法的调用完毕而消失
初始化值不同 有默认的初始化值 没有默认的初始化值,必须先定义,赋值,才能使用

类那(内)牲畜(生初)

面向对象的三大特征

封装、继承、多态

封装的作用和原则

作用

​ 封装是将对象的属性(成员变量)和行为(成员方法)结合在一起,并隐藏内部的实现细节,只暴露出一个可以被外界访问的接口。

原则

  1. 使用private关键字对成员变量进行隐藏

被private修饰的成员变量,在类外部无法直接访问,类内部可以访问

  1. 提供对应的getXxx和setXxx方法给外界使用

使用idea自动生成 快捷键:alt + ins

给成员变量赋值的方式有哪些

  1. 构造方法

  2. set方法赋值

继承的优点和缺点

优点

​ 提高了代码的复用性维护性

复位(维)

缺点

​ 提高了类的耦合性,当父类发生变化时,子类也要跟着变化。

继承中成员变量、构造方法、成员方法的访问特点

成员变量

就近原则

构造方法

优先完成父类的构造初始化

成员方法

优先访问子类的成员方法

方法重载和方法重写的区别

方法重载:在同一个类中的多个方法之间,满足以下条件的构成重载:

  1. 方法名相同

  2. 参数列表不同

  3. 与返回值无关

方法重写:子类中重写和父类中一模一样的成员方法

  1. 方法名相同

  2. 参数列表相同

  3. 与返回值相同

package、import、class的顺序关系

package > import > class

  1. package:一个类中只能有一个

  2. import:一个类中可以有多个

  3. class:可以是多个,推荐是一个

四种权限修饰符

权限修饰符 同类 无关类/子类-同包 子类-不同包 不同包
private-私有 1
default-默认(空着不写) 1 1
protected-受保护 1 1 1
public-公有 1 1 1 1

1表示“可访问”

final特点

  1. final修饰成员变量,表明该变量是一个常量,在定义的时候就必须要赋值,不能再次赋值

  2. final修饰成员方法,该方法不能被重写

  3. final修饰类,该类不能被继承

  4. final修饰局部变量

    final修饰基本数据类型变量:基本数据类型的不能发生改变

    final修饰引用数据类型变量:引用数据类型的地址值不能发生改变

static的作用和特点

作用

  1. 被类的所有对象共享

  2. 可以通过类名调用,也可以通过对象名调用

特点

静态只能访问静态,非静态可以访问所有

静态代码块、构造代码块、构造方法的执行顺序和特点

执行顺序

静态代码块—->构造代码块—->构造方法

特点

静态代码块:只执行一次

构造代码块:执行多次,每次执行构造方法,构造代码块都会执行一次。

多态的前提

  1. 要有继承或者实现关系

  2. 要有方法重写

  3. 要有父类引用指向子类对象

多态中的成员访问特点

成员变量:编译看左边(父类),运行看左边

成员方法:编译看左边(父类),运行看右边(子类)

抽象类的特点

  1. 抽象类和抽象方法都必须使用abstract修饰

  2. 类中如果有抽象方法,该类必须定义成抽象类

  3. 抽象类中可以有抽象方法,也可以有非抽象方法

  4. 抽象类的子类可以是抽象类,也可以是具体类,如果是具体类需要重写所有的抽象方法

  5. 抽象类中可以有成员变量、构造方法、成员方法

  6. 抽象类不能直接初始化,需要依赖具体子类,使用多态的方式创建对象

背诵技巧:前三条只涉及类和方法,后三条和子类和类的成员有关。

抽象类的成员特点

成员变量

变量或常量

构造方法

无参构造或带参构造

成员方法

抽象方法或普通方法

接口中成员变量和成员方法的默认修饰符

成员变量

public、static、final

成员方法

public abstract

接口的成员特点

成员变量

只能是常量

构造方法

接口没有构造方法,因为接口中没有需要初始化的成员变量(常量)

成员方法

只能是抽象方法(JDK8以前)

接口和抽象类的区别

  1. 抽象类需要被继承,只能单继承;接口需要被实现,可以多实现
  2. 抽象类的继承,描述的是is a的关系,是共性关系;接口的实现,描述的是has a的关系,是额外关系
  3. 抽象类中可以定义常量,也可以定义变量;接口中只能定义常量
  4. 抽象类可以有构造方法;接口没有构造方法
  5. 抽象类中可以定义普通方法,也可以定义抽象方法;接口中只能定义抽象方法(JDK8以前)

背诵技巧:继承、性质、成员特点比较;背了这个相当于背了抽象类和接口的成员特点。

多态的三种方式

  1. 普通类多态
1
2
Animal animal = new Cat();
// Animal 是一个普通类
  1. 抽象类多态
1
2
Animal animal = new Cat();
// Animal 是一个抽象类
  1. 接口多态
1
2
Flyable bird = new Bird();
// Flyable 是一个接口

内部类的分类

  1. 成员内部类

  2. 局部内部类

  3. 静态内部类

  4. 匿名内部类(重要

你(匿)竟(静)成局

匿名内部类的前提和本质

前提:存在一个或者接口

本质:是一个对象

注意:这里的类可以是普通类也可以是一个抽象类

Object类中有哪些常见的方法

  1. toString()
  2. equals(Object obj)
  3. hashCode()
  4. wait()
  5. notify()

部分方法的详细介绍

  1. String toString() 返回对象的字符串表示形式,在javabean中必须要被重写

    1. 重写前显示对象地址值
    2. 重写后显示对象的字符串表示
  2. boolean equals(Object obj) 指示是否有其他对象”等于”这一个,也需要被重写

    1. 重写前判断地址值是否相等
    2. 重写后判断属性值是否相等
1
2
3
4
5
6
7
8
9
10
11
12
/*

* 测试Object类的相关方法
* */
public class ObjectDemo1 {
public static void main(String[] args) {
Student student = new Student();
System.out.println(student);
//com.hu.obj.Student@1b6d3586
System.out.println(student.toString());
}
}

Object类中的finalize方法的作用

Object类中,有一个protected void finalize() ,在JVM清理完垃圾之后,自动调用这个方法

1
2
3
4
5
6
public class Animal {
@Override
protected void finalize() throws Throwable {
System.out.println("垃圾被回收了");
}
}

Java中垃圾回收机制(gc方法)的原理

  1. 垃圾回收机制只回收JVM中堆内存的对象
  2. 堆内存中的对象在长时间不用,垃圾回收机制会自动回收
  3. 回收时间不确定

基本数据类型和包装类的对应关系

基本数据类型 包装类
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean

基本数据类型与字符串互转

基本数据类型怎么转字符串?

  1. String s1 = 12.3 + “”;

  2. String s2 = String.valueOf(12);

字符串怎么转基本数据类型?

Integer类的static int parseInt(String s) 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
* 字符串和基本数据类型之间的相互转换
* */
public class IntegerDemo3 {
public static void main(String[] args) {
//基本数据类型--------->字符串
int i = 10;
String s = i + "";
String s1 = 12.3 + "";
String s2 = String.valueOf(12);
String s3 = String.valueOf(12.3);

//字符串------->基本数据类型
int i1 = Integer.parseInt("10086");
float v = Float.parseFloat("12.3F");
System.out.println(v);

long l = Long.parseLong("100");
System.out.println(l);
}
}

length和length()、size()的区别

length:数组的长度,是属性

length():字符串的长度,是方法

size() :集合的长度

背诵技巧:数字集

String、StringBuffer、StringBuilder的区别

特性 String StringBuffer StringBuilder
是否可变 不可变 可变 可变
是否线程安全 不安全 安全 不安全

编译期异常和运行期异常的区别

编译期异常 运行期异常
时机 在执行编译命令(javac)的时候,出现异常 在执行运行命令(java)的时候,出现异常
idea显示 在Idea中有红色波浪线提示 在Idea中没有红色波浪线提示
继承关系 都继承自Exception 都继承自RuntimeException

是(时)IG(继)

try—catch和throws的区别

try—catch

通过catch抓取指定的异常,在catch中强行处理异常,就不会再次出现异常

throws

把异常抛给调用该方法的上一级,如果一直往上抛,最终由JVM按照异常的默认处理机制处理。

throw和throws的区别

throw

  1. 位置:用在方法体内

  2. 后面跟的是:异常的对象,只跟一个对象

  3. 执行该关键字代码,一定会出现异常

throws

  1. 位置:用在方法的签名位置

  2. 后面跟的是:异常名,而且可以是多个

  3. 执行该关键字代码,不一定出异常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
* throw关键字
*
* */
public class ExceptionDemo5 {
public static void main(String[] args) {
int a = 10;
int b = 0;

if (b == 0) {
throw new ArithmeticException("b=0");
} else {
int i = a / b;
}

System.out.println("over");
}
}

设计模式的七大原则是什么

开闭原则

单一职责原则

里氏替换原则

依赖倒转原则

接口隔离原则

迪米特法则(最少知道原则)

合成复用原则

背诵口诀:合理(里)解(接)开第(迪)一(依)弹(单)

Java中对方法的增强的方式有哪些

继承

增强的内容不能改变,被增强对象不能改变

装饰者模式/静态代理模式

增强的内容不能改变,被增强对象能改变

动态代理

增强的内容能改变,被增强对象能改变

背诵:(与String、StringBuffer和StringBuilder相对应)

继承方式 继承 动态代理 装饰者模式/静态代理模式
被增强对象 不可变 可变 可变
增强的内容 不可变 可变 不可变

集合和数组的区别是什么

长度区别

集合的长度可以改变,数组的长度不能改变

元素的数据类型

集合中只能存储引用数据类型数据

数组中既可以存储基本数据类型,也可以存储引用数据类型

存储的数据不同

集合可以存储单列数据,也可以存储双列数据

数组只能存储单列数据

背诵:原(元)长存

在List集合中删除元素的注意事项

反向遍历

ArrayList、LinkedList、Vector的区别(需检查vector)

ArrayList

A:底层结构是数组(查询快、增删慢)

B:线程不安全、效率高

LinkedList

A:底层结构是链表(查询慢、增删快)

B:线程不安全、效率高

Vector

A:底层结构是数组(查询快、增删慢)

B:线程安全、效率低

ArrayList集合底层结构是什么

Object数组

ArrayList集合的扩容机制

如果第一次使用无参构造,那么第一次添加元素的时候会扩容成长度为10的数组,当添加的元素超过数组的长度时,按照1.5倍扩容

1
int newCapacity = oldCapacity + (oldCapacity >> 1);

HashSet、LinkedHashSet、TreeSet集合的底层结构

HashSet

底层结构:哈希表

数组+链表 (JDK7及以前)

数组+链表+红黑树 (JDK8及以后)

特点:存取无序、无索引、元素唯一

LinkedHashSet

底层结构:链表+哈希表

特点:存取有序、无索引、元素唯一

TreeSet

底层结构:二叉树

特点:按照给定的规则排序、无索引、元素唯一

HashSet集合是怎么保证元素唯一性的

依赖hashCode和equals两个方法

先通过hash计算在数组中的位置,然后用equals方法与链表或红黑树中的每个元素做对比,如果有相同元素就覆盖,如果没有相同元素则添加。

TreeSet集合是怎么保证元素唯一性的

比较接口中重写的比较方法,返回值为0表示元素重复

可变参数的本质是什么

是一个数组

HashMap集合的底层结构

JDK7及以前:数组+链表

JDK8及以后:数组+链表+红黑树

HashMap集合的无参构造,在第一次添加元素的时候数组的初始大小

16

HashMap集合加载因子为什么是0.75

泊松分布

加载因子较大,哈希冲突的概率变大,导致链表过长,查询效率变低

加载因子过小,数据过于稀疏,会导致空间浪费

HashMap集合中链表什么时候转红黑树

链表的长度达到阈值8,且数组的长度大于64

HashMap集合中红黑树什么时候转链表

链表的长度达到6

HashMap集合中数组的扩容为什么都是2的n次幂

因为在添加元素计算数组的下标时,使用的是key的哈希值和数组的长度减一做&运算

HashMap集合添加元素的时候,计算数组下标为什么不使用取余,而使用按位与

  • 按位与的效率较高

  • 取余可能出现负数

File和IO的区别

  • file用来操作文件载体
  • io用来操作文件内容

flush和close的区别

  • flush:将数据从操作系统缓存刷新到硬盘

  • close:将数据从操作系统缓存刷新到硬盘,然后释放资源

IO流中的相对路径和绝对路径

  • IO流中的相对路径,是相对于Project(项目)路径

  • 绝对路径:Windows是相对于盘符开始路径,Linux是相对于根路径开始

程序、进程、线程、协程的区别

  1. 程序:没有运行的代码
  2. 进程:运行起来的代码,资源分配和调度的基本单位
  3. 线程:进程执行的最小单位
  4. 协程:也称为虚拟线程,JDK19出现的;协程的本质是一种用户态的轻量级线程,一个线程能支持多个协程的运行,且多个协程能并发执行

并发和并行的区别

  • 并发:多个事件在同一个时间段内发生(实际中研究的)
  • 并行:多个事件在同一个时间点内发生(理想状态)

run和start的区别

  • run方法:调用不会开启新的线程,只能在main方法中执行(单线程)

  • start方法:调用会开启一个新的线程,让jvm调用run方法在新的线程中执行(多线程)

描述线程的生命周期

新建、就绪、运行、阻塞、死亡

HashMap和Hashtable的区别

HashMap Hashtable
是否允许null值 允许null键和null值 不允许null键和null值
线程是否安全 线程不安全,效率高 线程安全的,效率低

volatile关键字的作用

在多线程中有三个常见问题:可见性、有序性、原子性

volatile可以解决可见性和有序性,不能解决原子性

使用线程池的好处是什么

  1. 避免了频繁地创建和销毁线程
  2. 提高了每个线程的利用率

ThreadPoolExecutor的七大参数,以及分别表示什么意思

背诵技巧:前四个是线程相关的,后三个是整体线程池相关的。

ThreadPoolExecutor线程池的工作原理

实现多线程的方式

  1. 继承Thread类
  2. 实现Runnable接口
  3. 实现Callable接口
  4. 使用线程池

类加载的过程

加载—>连接(验证、准备、解析)—>初始化—>使用—>卸载

类加载器的分类

从上到下依次是

启动类加载器 扩展类加载器 系统类加载器 自定义类加载器
名称 Bootstrap class loader Platform/Extension class loader App/System class loader
加载路径 JAVA_HOME/jre/lib JAVA_HOME/jre/lib/ext 类路径(src目录) 自定义

双亲委派机制的原理

​ 如果一个类加载器收到了类加载请求,默认先将该请求委托给其父级加载器处理。只有当父级加载器无法加载该类时,才会尝试自行加载。双亲委派机制能够提高安全性,避免了类的重复加载。

特点

  1. 向上找缓存
  2. 向下找对应的类加载器

图解

反射获取字节码文件的三种方式

(1)类名.class

(2)对象.getClass()

(3)Class.forName(String 全类名)

​ 全类名:包名+类名

反射中getMethods和getDeclaredMethods方法的区别

  1. 方法 getMethods() :获取当前类的所有的public修饰的+继承自父类的public修饰成员方法对象

  2. 方法 getDeclaredMethods() :获取当前类的所有成员方法对象,无视权限修饰符

注解的属性(抽象方法)的返回值要求

  1. 基本数据类型

  2. String

  3. 枚举

  4. 注解

  5. 以上数据类型的数组形式

注意事项:返回值不能是void

lambda表达式和匿名内部类的区别

匿名内部类 lambda表达式
所需的类型不同 匿名内部类可以new接口、抽象类、普通类 lambda表达式只能是接口
使用限制 匿名内部类的接口中,可以有一个也可以有多个抽象方法 lambda表达式的接口中,只能有一个抽象方法
生成字节码文件的方式不同 匿名内部类的字节码文件在硬盘中 lambda表达式的字节码文件在内存中

背诵技巧:省(生)市(使)所

jdk8有哪些新特性

  1. lambda表达式

  2. 接口的组成更新(默认方法和静态方法)。

  3. Stream流

  4. 新日期类Localdate和LocalDatetime

注意:接口的组成更新产生了函数式接口的说法,jdk8以前接口只能由抽象方法。

在jdbc中事务是由谁管理的

JDBC中事务是由Connection管理的

start transaction

1
2
void setAutoCommit(boolean autoCommit)  
参数autoCommit: true---自动提交 **false**---手动提交

commit

1
void commit()  

rollback

1
void rollback()  

get请求和post请求的区别

get

  1. 安全性低,速度快
  2. 使用场景:搜索
  3. 参数的大小会受到限制,最大几十kb
  4. 提交的参数在地址栏中可见

post

  1. 安全性高,速度慢
  2. 使用场景:上传文件
  3. 参数的大小没有限制
  4. 提交的参数在地址栏不可见

背诵技巧:俺(安)是(使)三(参)体(提)

input标签中type属性有哪些取值,分别表示什么

列举

type取值 描述
text 文本框
password 密码框
radio 单选框
checkbox 复选框
file 上传头像
hidden 隐藏字段
submit 提交按钮
reset 重置按钮
button 普通按钮
image 图片按钮

背诵技巧:文秘(密)担(单)负(复)上瘾重提谱(普)图

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="#" method="post">
<input type="hidden" name="id" value="123">

<label for="username">用户名:</label>
<input type="text" name="username" id="username"><br>

<label for="password">密码:</label>
<input type="password" name="password" id="password"><br>

性别:
<input type="radio" name="gender" value="1" id="male"> <label for="male"></label>
<input type="radio" name="gender" value="2" id="female"> <label for="female"></label>
<br>

爱好:
<input type="checkbox" name="hobby" value="1"> 旅游
<input type="checkbox" name="hobby" value="2"> 电影
<input type="checkbox" name="hobby" value="3"> 游戏
<br>

头像:
<input type="file"><br>

城市:
<select name="city">
<option>北京</option>
<option value="shanghai">上海</option>
<option>广州</option>
</select>
<br>

个人描述:
<textarea cols="20" rows="5" name="desc"></textarea>
<br>
<br>
<input type="submit" value="免费注册">
<input type="reset" value="重置">
<input type="button" value="一个按钮">
</form>
</body>
</html>

效果

特别注意

HashMap数组扩容的两种情况

  1. 数组长度<64,链表长度达到阈值8
  2. 添加元素超过承重