赞
踩
实现 Cloneable 接口并重写 Object 类中的 clone()方法;
实现 Serializable 接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆
3个对象, s是引用对象, 放到栈里, s中存储的是内存地址,
new String是一个对象, 放到堆里, "abc"是一个字符串对象, 放到堆里.
应用层, 表示层, 会话层, 传输层, 网络层, 数据链路层, 物理层.
http协议, https协议, FTP协议, SIP协议, POP3和SMTP协议等
http不安全, https协议安全, 因为https协议在传输过程中, 传输的内容会进行加解密.
原理是跟国家有关部门花钱申请CA证书, 将证书部署到tomcat服务器中, 那么传输的内容会经过CA证书进行加解密, 这样传输的内容是安全的.
传输层只有两个协议, 一个是tcp, 一个是udp
tcp: 传输过程中有三次握手, 四次挥手过程. 所以传输的速度比udp慢, 但是不容易丢数据包.(HTTP协议是基于TCP协议的,发送数据之前需要建立好连接;)
udp: 传输过程是无状态的, 传输速度快, 但是容易丢数据包. 主要使用在视频, 语音传输中.
http协议1.0是短连接, http协议是1.1那么是长连接.
2XX: 成功
3XX: 重定向
4XX: 访问的资源错误, 或者不存在.
5XX: 服务器内部错误.也就是java代码中出现了问题.
get: 一般用作查询
post: 一般用作添加
put: 一般用作修改
delete: 一般用作删除.
options: 一般前后端分离的项目中使用options发送一个简单的请求, 测试请求是否成功, 如果成功才会继续发业务请求(get, post, put, delete), 如果options尝试访问失败, 那么不会再发业务请求.
public class TryDemo {
public static void main(String[] args) {
System.out.println(test());
}
public static int test() {
try {
return 1;
} catch (Exception e) {
return 2;
} finally {
System.out.print("3");
}
}
}
在 return 前会先执⾏ finally 语句块,所以是先输出 finally ⾥的 3,再输出 return 的 1。
如果finally里有return则不会执行try里面的return。
Java 中的基本数据类型只有8个:byte、short、int、long、float、double、char、
boolean;除了基本类型,剩下的都是引⽤类型。
基本数据类型:数据直接存储在栈上
引⽤数据类型区别:数据存储在堆上,栈上只存储引⽤地址。
char: 1个字节
short: 2个字节
int: 4个字节
long: 4个字节
int为4个字节:1字节=8位,所以int为32位在计算机中存储的二进制位数。
如果没有符号位的话: 就是32位:表示数的范围为2的32次方(可以举例数字就明白了).
最大的整数为:2的32次方-1。
就是这么大:
unsigned int 0~4294967295
使用两个token,一个是真正的access_token时效短(2h),另外一个refresh_token时效长(7day)用于刷新token。用redis存储access_token,设置过期时间。
情况1:refresh_token过期,重新登录获取access_token
情况2:refresh_token没过期,access_token过期,不用登录,后端刷新access_token。
避免使用多个锁:尽量减少代码中使用多个锁的情况,减少死锁的概率。
避免循环等待:尽量避免线程之间形成循环等待的情况,可以通过统一获取锁的顺序来避免循环等待。
使用定时锁:在获取锁的时候设置超时时间,如果超过一定时间还未获取到锁,则放弃锁并进行相应的处理。
使用线程池:使用线程池来管理线程的执行顺序,避免线程之间的竞争和死锁。
使用并发工具类:使用Java并发工具类如ReentrantLock、Semaphore等来替代synchronized关键字,这些工具类提供了更灵活的锁管理方式。
使用死锁检测工具:可以使用一些工具来检测死锁的发生,如jstack、jconsole等,及时发现并解决死锁问题。
Stream API:(集合、或者数组创建stream,中间操作,过滤、map,终止操作)
1.根据List获取流
2.根据Set获取流
3.根据Map获取流
3.1根据Map集合的键来获取流
3.2根据Map集合的值获取流
3.3根据Map集合的键值对对象获取流
4.根据数组获取流
Java8新增的日期类主要有三个:
LocalDate:表示日期(年月日)
LocalTime :表示时间(时分秒)
LocalDateTime:表示时间+ 日期 (年月日时分秒),是java8最常用的日期类
包装类是将基本类型转化为对象的机制,基本数据类型不具备对象的特性,不能直接调方法或者参与面向对象的操作。所以需要使用包装类。
可以直接使用equals方法进行比较,因为包装类是对象,对象之间比较值应该用equals方法。
功能:1.将基本类型转化为包装类 2,提供了和基本数据类型相对应的静态常量和方法
3,支持自动拆箱和装箱 4,提供一些额外的功能方法,如对数字进行格式化,转化
基本类型,引用类型(对象,接口,数组,字符串)
是java提供对频繁创建字符串的一种解决方案,同一个对象创建多次,占用多个内存空间。
所有在创建一个字符串时,会先判断字符串常量池是否已经存在该字符串,不存在则创建,存在则返回这个对象的地址。
start():线程启动时调用,线程处于就绪状态;
run():线程运行时调用,线程处于运行状态;
可以保证线程安全,每个线程都会创建一个线程副本,set和get的值是同一个;
string类是不可变的(也就是说一旦创建了一个字符串对象,就不能再修改它的值。因此,每次对字符串进行操作时,都会创建一个新的字符串对象,这样会产生大量的临时对象,影响程序的性能。)
stringBuffer,可变的,它们可以更改已有对象中的字符内容,而不必创建新的对象,线程安全(使⽤ synchronized 来保证线程安全);
stringBuilder是可变的,它们可以更改已有对象中的字符内容,而不必创建新的对象,线程不安全;
1,字符串的重用(通过调用intern()
方法,可以将字符串对象放入字符串常量池中,并返回常量池中的引用。这样可以避免创建多个相同内容的字符串对象,节省内存空间。),2,字符串的比较和优化(由于字符串常量池中的字符串是唯一的,所以可以使用==
运算符来比较字符串对象的引用是否相等,而不需要使用equals()
方法进行内容比较,提高比较的效率。)
反射是java提供的一种机制,这个机制可以动态的获取一个类或对象的内部结构(属性,方法,接口,父类),还可以调用方法和修改属性。
自己写的工具类,框架
常用API
1,Class:表示字节码的文件对象
2,Method:对方法的封装
3,Field:对属性的封装
4,Parameter:方法形参的封装
5,Constructor:获取构造函数
接口是一组抽象方法的集合,没有具体实现。接口定义了一个规范,要求实现该接口的类必须提供对应的方法实现。接口中的所有方法默认都是public,而且不能包含成员变量。一个类可以实现多个接口,从而实现多重继承。
抽象类是一个类,它可以包含抽象方法和具体方法。抽象方法是没有具体实现的方法,需要由子类来实现。抽象类可以包含成员变量,可以有构造方法和非抽象方法。一个类只能继承一个抽象类,但是可以同时实现多个接口。
1、接口只定义了抽象方法,没有具体实现,而抽象类可以包含抽象方法和具体方法。
2、一个类可以实现多个接口,但只能继承一个抽象类。
3、接口中的所有方法默认都是public,而抽象类可以有不同的访问控制符。
值传递:在方法调用时,将实际参数的副本传递给方法,当你在方法内部修改参数的值时,只会影响副本,不会影响原始的变量。(基本类型的传递)
引用传递:在方法内部操作会影响到原始数据,但如果重新分配一个新的对象,原始对象不会改变。(对象的传递)
重载:方法名称相同,参数列表不同,和返回值没有关系;
重写:方法名称相同,参数列表相同,返回值相同;
sleep属于Thread类,wait属于object类
sleep()睡眠时不会释放锁,wait会
sleep()睡眠指定时间会自动唤醒,wait()需要手动唤醒
懒汉式:在第一次调用获取实例的方法才创建,可能存在线程安全问题,(非原子操作懒汉式在第一次获取实例时才进行实例化操作,然而实例化操作通常不是原子操作,而是包括了对变量的初始化、内存分配和赋值等多个步骤。在多线程环境下,如果两个线程同时通过了实例是否为空的判断,然后都尝试去实例化对象,就有可能导致创建多个实例的情况。)
饿汉式:在类加载的时候就会创建,不存在线程安全问题。
悲观锁:的基本思想是,在整个数据处理过程中,将数据加锁,防止其他事务同时修改数据。
当一个事务访问数据时,悲观锁会认为其他事务可能会对数据进行修改,因此会直接对数据进行加锁,使其他事务无法访问或修改数据,直到当前事务完成。
悲观锁适用于并发写入较多、冲突概率较高的场景,但它的缺点是会导致其他事务等待,并发性能相对较低。
乐观锁的基本思想是,假设在整个数据处理过程中,不会有其他事务修改数据,因此不进行加锁操作。
当一个事务要对数据进行修改时,乐观锁不会立即加锁,而是在提交时检查是否有其他事务修改过数据。如果有冲突,则放弃当前事务的修改,重新尝试,直到成功或达到一定的尝试次数。(一般用数据版本机制或者CAS:比较并交换)。
乐观锁适用于并发读取较多、冲突概率较低的场景,它不会对数据进行加锁,因此并发性能相对较高,但需要增加冲突检测和重试机制。
数组+链表+红黑树,先通过key计算出hascode值,通过hash函数算出对应在数组的下标,
不同的key可能算出相同的hashcode。所以当发生hash冲突时,hashmap采用链表法,当超过一定的阈值时,自动转为红黑树。(当元素超过数组的0.75倍会扩容成原来2倍)
方法区放静态方法,静态变量,字符串常量
堆区:放对象
栈区:放变量
1,synchronized是一个关键字,而lock是一个接口。
发生异常时synchronized会自动释放锁,而lock需要手动释放。如果没有释放容易造成死锁问题,所以需要在finally里调用unlock方法释放。
2,lock是可中断锁,而synchronized不是。
3,synchronized是重量级锁
4,Lock 获取锁和释放锁都是显式的,不像 synchronized 是隐式的。所以 synchronized 会在抛异常时自动释放锁,而 Lock 只能是主动释放,加解锁都必须有显式的代码控制。
volatile关键字保证了线程的可见性,就是说当一个修改volatile关键字的变量的值,其他线程立马可以看见。同时volatile关键字还有防止指令重排序。轻量级性能更快,只能保证单个读/写操作的原子性,无法保证整个操作序列的原子性。
==比较基本类型的时候是比较值是否相同,比较对象时是比较地址。
equals是对内容的比较,需要重写equals方法。
接口幂等性问题,后端第一接收到提交请求时,后端生成唯一标识,存储在缓存或者会话中返回给前端,当后续请求到达时,将唯一标识一起携带,后端先检测是否携带有唯一标识,有就拒绝,没有就处理。
list是一个接口,而linklist实现了这个接口。
List 使用数组作为底层数据结构,可以通过索引快速定位元素,因此在查询和搜索元素时性能更好。但在插入和删除元素时,需要移动其他元素来维持顺序,因此性能较差。(查询快,修改慢)
LinkedList 使用双向链表作为底层数据结构,插入和删除元素只需要修改相邻节点的指针,因此性能更好。但在查询和搜索元素时需要遍历整个链表,性能较差。(修改快,查询慢)
后记
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。