【JAVA零散知识点】


引用类型与基本类型

  • Java有八个基本变量类型:int,short,long,float,double,byte,char,boolean
  • 区别:
    • 基本数据类型在被创建时,在栈上给其划分一块内存,将数值直接存储在栈上。
    • 引用数据类型在被创建时,首先要在栈上给其引用(句柄)分配一块内存,而对象的具体信息都存储在堆内存上,然后由栈上面的引用指向堆中对象的地址。

Equals方法与HasCode方法

  • equals方法用于定义对象的相等性:自反性、对称性、传递性、一致性、非null
  • hashCode方法返回对象的散列码(哈希码)
    • Java约定,如果两个对象通过 equals() 方法比较是相等的,那么它们的 hashCode() 方法返回的值应该相等
    • 为了保持一致性和正确性,在重写equals方法时,必须同时重写hashCode方法
    • 在集合类中,当我们使用 equals() 方法来比较两个对象是否相等时,首先会比较它们的 hashCode() 值,只有当 hashCode()值相等时,才会进一步比较 equals()

创建实例的方法(四种)

  • 使用new关键字:
    • 使用new关键字调用类的构造方法来创建实例。
    • 例如:ClassName obj = new ClassName();
  • 使用反射
    • 通过java.lang.reflect包中的相关类和方法,在运行时动态地创建类的实例。
    • 例如:Class<?> clazz = Class.forName(“ClassName”); Object obj = clazz.newInstance();
  • 使用clone()方法
    • 如果类实现了Cloneable接口,并重写了clone()方法,可以使用clone()方法来创建对象的副本。
    • 例如:ClassName obj = new ClassName(); ClassName objCopy = obj.clone();
  • 使用工厂方法
    • 在类中定义一个静态方法,用于创建类的实例。这种方法隐藏了实例化过程的细节。

HashMap

- HashMap:总体是数组+链表的存储结构,从JDK1.8开始,当数组的长度大于64,且链表的长度大于8的时候,会把链表转为红黑树。
- HashMap是非线程安全的,只适用于单线程环境下(多线程可能会出现同时向一个位置插值,会出现覆盖),多线程环境下可以采用concurrent并发包下的concurrentHashMap。
- HashMap实现了Serializable接口,因此它支持序列化,实现了Cloneable接口,能被克隆。
- HashMap允许键值为null,但concurrentHashMap不允许,原因是获取键值返回为null,出现歧义,无法判断是不存在这个键值还是键值为null(锁不住null)。所以键值为null会抛出NullPointerException异常。
- Cloneable是一个接口,实现这个接口后,可以在类中重写Object中的clone方法,然后通过类调用clone方法进行克隆,如果不实现Cloneable接口,则会抛出CloneNotSupportedException异常。
- synchronized:加锁,表示同一时间内只能有一个线程来执行此方法。

Java中的容器

  • java容器:Java容器类包含List、ArrayList、Vector及map、HashTable、HashMap、Hashset
  • 集合(Collection):集合是一组对象的容器,可以存储并操作多个对象。常用的集合接口有List、Set和Queue。
    • List:List是有序的集合,允许重复元素。常见的实现类有ArrayList(动态数组)和LinkedList(双向链表)。(Vector、Stack)
    • Set:Set是不允许重复元素的集合,保证元素的唯一性。常见的实现类有HashSet(基于哈希表)和TreeSet(基于红黑树)。(LinkedHashSet)
    • Queue:Queue是一种队列,按照先进先出(FIFO)的原则对元素进行操作。常见的实现类有LinkedList和PriorityQueue。
  • 映射(Map):映射是一种键值对(Key-Value)的容器,通过键来唯一标识和访问值。常用的映射接口是Map,其中常见的实现类有HashMap(基于哈希表)和TreeMap(基于红黑树)。
    • HashMap:基于哈希表实现,使用键值对存储数据,无序且不允许重复键。(LinkedHashMap)
    • TreeMap:基于红黑树实现,按照键的自然顺序或自定义顺序进行排序。

Java中的线程

  • 创建线程的方法:创建线程的方式有 继承Thread类 、 实现Runnable接口 、 实现Callable接口 、 使用ThreadPoolExecutor类
  • 继承Thread类 、 实现Runnable接口,这2种方式都有一个缺陷就是:在执行完任务之后无法获取执行结果。
  • Callable接口代表一段可以调用并返回结果的代码;Future接口表示异步任务,是还没有完成的任务给出的未来结果。所以说Callable用于产生结果,Future用于获取结果。
  • ThreadPoolExecutor线程池的几个重要参数:
    • corePoolSize(核心线程数):即使没有任务,线程池也会保持核心线程的数量。(硬件-CPU核数、软件-区分io密集型和CPU密集型)
    • maxPoolSize(最大线程数):线程池能允许的最大线程数量。
    • queueCapacity(任务队列容量):当任务队列已满,但当前线程数未达到最大线程数时,创建新的线程来执行任务
    • keepAliveTime(线程保活时间):当线程执行时间超过保活时间后,线程会被回收,任务终止。
    • allowCoreThreadTimeout(允许核心线程超时退出):
    • rejectedExecutionHandler(拒绝策略):
      • AbortPolicy :(默认) 丢掉这个任务并抛出RejectedExecutionException异常
      • DiscardPolicy :直接丢掉任务,不返回任何异常
      • DiscardOldestPolicy :丢弃最老的。也就是说如果队列满了,会将最早进入队列的任务删掉腾出空间,再尝试加入队列。因为队列是队尾进,队头出,所以队头元素是最老的,因此每次都是移除对头元素后再尝试入队。
      • CallerRunsPolicy : 添加到线程池失败,那么主线程会自己去执行该任务,不会等待线程池中的线程去执行。
      • 自定义 : 实现RejectedExecutionHandler接口,并且实现rejectedExecution方法就可以了。具体的逻辑就在rejectedExecution方法里去定义。

Java虚拟机

  • 组成:类加载器、运行时数据区、执行引擎、本地方法接口、垃圾回收器和内存管理

    • 类加载器:负责将字节码(.class文件)加载到内存中,并进行链接、验证和初始化操作。
    • 运行时数据区:
      • 方法区(Method Area)存储类的结构信息、常量、静态变量等。
      • (Heap)用于存储对象实例和数组等动态分配的数据。
      • (Stack)存储方法的执行栈和局部变量。
      • 程序计数器(Program Counter)用于指示当前线程执行的字节码指令。
      • 本地方法栈(Native Method Stack)用于执行本地方法。
    • 执行引擎:可以采用解释执行或即时编译的方式来执行字节码。
    • 本地方法接口:允许Java代码调用本地方法(用其他编程语言如C或C++编写的方法)。
    • 垃圾回收器和内存管理:识别堆内存的不可达对象,并释放它们占用的内存空间。(标记-清除、复制、标记-整理)
      在这里插入图片描述
  • java文件的加载过程:(加载-链接-初始化)

    • ①加载:文件被javac编译为.class文件
    • ②验证:class文件的字节流中包含的信息是否符合当前虚拟机的要求,并且不会危害虚拟机自身的安全
    • ③准备:在方法区中分配这些变量所使用的内存空间(static int v = 8080 会被赋值为0;static final int v = 8080 会被赋值为8080)
    • ④解析/识别:虚拟机将常量池中的符号引用替换为直接引用
    • ⑤初始化
  • JVM的垃圾回收机制

    • Serial:年轻代、标记-复制、单线程、Stop-the-World ~ Serial Old:老年代、标记-整理、单线程、Stop-the-World
    • Parallel Scavenge:年轻代、标记-复制、多线程、Stop-the-World、关注吞吐量 ~ Parallel Old:老年代、标记-整理、多线程、Stop-the-World (java8默认)
    • ParNew:年轻代、标记-复制、多线程、STW ~ CMS:老年代、标记-清除、多线程、STW时间短、注重响应速度
    • G1(Garbage First):全局、分代收集、并发标记、空间整理、可预测的停顿时间

Spring

  • SpringBoot 与 SpringCloud
    • Spring Boot专注于快速方便的开发单个服务;
    • Spring Cloud 关注的是多个服务之间的协调管理,为各个服务提供配置,服务发现,断路器,路由,微代理等一系列集成服务。(SCM版本:Hoxton)
    • Spring boot可以离开Spring Cloud独立使用开发项目,但是Spring Cloud离不开Spring boot,属于依赖的关系。
  • Spring是一个面向切面控制反转的容器框架(AOP和IOC)
    • AOP的实现有AspectJ、JDK动态代理、CGLIB动态代理
    • IOC控制反转,有专门的容器专门管理这些对象的生命周期,控制对象的创建和外部资源的获取。
    • IOC依赖注入、Spring依赖注入(DI):在 Spring IOC 容器创建对象的过程中,将所依赖的对象通过配置进行注入。我们可以通过依赖注入的方式来降低对象间的耦合度。
      • 属性注入:通过setXXX方法注入(setter injection)
      • 构造器注入:(constructor injection)
      • 基于字段变量field的依赖注入:@Autowired,@Resource(interface injection)
    • Bean的生命周期-实例化Instantiation 、属性赋值Populate 、初始化Initalization 、销毁Destruction
  • Bean的生命周期
    • 实例化:Spring容器会根据Bean定义和配置,使用构造函数或工厂方法创建Bean的实例对象。
    • 属性注入:在Bean实例化后,Spring容器会将配置中定义的属性值注入到Bean实例中。这可以通过使用构造函数注入、设值注入或注解注入等方式完成。
    • Bean的初始化:一旦属性注入完成,Spring容器会调用Bean的初始化回调方法。开发者可以在Bean类中定义初始化方法,用于执行特定的初始化逻辑。
      初始化方法可以通过实现InitializingBean接口的afterPropertiesSet()方法,或者在配置中使用init-method属性来指定。
    • 使用Bean:一旦Bean初始化完成,它就准备好可以被使用了。在此阶段,开发者可以调用Bean的方法来执行业务逻辑。
    • Bean的销毁:当应用程序关闭或Spring容器销毁时,会触发Bean的销毁过程。开发者可以定义销毁回调方法,用于进行资源的释放或其他清理操作。
      销毁方法可以通过实现DisposableBean接口的destroy()方法,或者在配置中使用destroy-method属性来指定。
  • Spring事务:Spring事务的本质其实就是数据库对事务的支持
    • 实现事物的两种方式::编程式:beginTransaction()、commit()、rollback()等事务管理相关的方法,声明式:
      利用注解Transactional或者aop配置
    • Atomicity-原子性:事务要么全部都被执行,要么就全都不被执行,如果有子事务提交失败,那么其他子事务对数据库的操作将被回滚,数据库回到事务提交前的状态;如果全部子事务都提交成功,则所有的数据库操作都会被提交;
    • Consistency-一致性:事务的执行使得数据库从一种正确状态转换成另一种正确状态;
    • Isolation-隔离性一个事务的执行不能被其他事务所影响;
    • Durability-持久性:事务一旦提交,就会永久保存在数据库中,及时数据库服务器发生故障,也不会丢失提交事务的操作。
    • 读未提交(Read Uncommitted)、读提交(Read Committed)、可重复读取(Repeatable Read)、序列化(Serializable)
    • 脏读、不可重复读、幻读。oracle默认(Read Committed),MySQL默认(Repeatable Read)。

常用的设计模式

  • 单例模式(Singleton)
    • 介绍:确保一个类只有一个实例,并提供全局访问点。
    • 示例:Java中的运行时环境(Runtime)就是一个单例对象,通过调用Runtime.getRuntime()方法获取该全局实例。
  • 工厂模式(Factory)
    • 介绍:通过一个工厂类创建对象,隐藏对象的实例化过程。
    • 示例:Java中的Calendar类通过Calendar.getInstance()方法获取日历实例,而具体的日历实现类由工厂类负责创建。
  • 观察者模式(Observer)
    • 介绍:对象之间定义一对多的依赖关系,当一个对象状态改变时,其他依赖它的对象会得到通知和更新。
    • 示例:Java中的观察者模式由java.util.Observer接口和java.util.Observable类实现,可以实现基于事件的通知机制。
  • 建造者模式(Builder)
    • 介绍:将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。
    • 示例:Java中的StringBuilder类用于构建可变字符串,可以通过链式调用不同的方法来逐步构建字符串对象。
  • 适配器模式(Adapter)
    • 介绍:将一个类的接口转换成另一个客户端所期望的接口,使得原本不兼容的类可以合作。
    • 示例:Java中的InputStreamReader类将字节流转换为字符流,提供了一个适配器,使得字节流可以按字符读取。
  • 装饰器模式(Decorator)
    • 介绍:动态地给一个对象添加额外的功能,避免通过继承产生大量的子类。
    • 示例:Java中的IO流的包装类,如BufferedReader,用于给低级别的字符流(如FileReader)提供缓冲功能。
  • 模板方法模式(Template Method)
    • 介绍:定义一个操作中的算法框架,而将一些步骤延迟到子类实现。
    • 示例:Java中的Applet类是一个抽象模板类,它定义了整个Applet的生命周期,具体实现由子类来完成。

杂项

- java的io流:字节流(InputStream、OutputStream)或 字符流(Reader、Writer)。
- java的反射机制:Reflection,Java的反射是指程序在运行期可以拿到一个对象的所有信息。
- java序列化:序列化就是一种用来处理对象流的机制。将对象的内容流化,将流化后的对象传输于网络之间。
- Serializable接口:启用其序列化功能的接口。实现java.io.Serializable 接口的类是可序列化的。没有实现此接口的类将不能使它们的任意状态被序列化或逆序列化。
- java中的字符串:String (线程安全),StringBuffer (线程安全),StringBuilder (线程不安全、效率高)
- OO(面向对象)的核心思想:封装、继承、多态
- 重载(相同的方法名、不同的参数参数):编译时多态性的体现,用统一的方式处理不同类型数据;重写(相同的方法名、参数):子类在继承父类的基础上,对父类方法的功能进行重写。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值