Java学习笔记基础

1.变量是存储数据的小空间不是里面的数据

2.变量只能存一个值,不允许重复定义,使用之前一定要赋值。一条语句可以定义多个变量,也可以连续赋值。

3.标识符的命名规则:由数字,字母,下划线,美元符组成,不能以数字开头,不能是关键字,区分大小写。

4.类型不一样不能运算,转换成同类型才能运算。

不同类型的数据进行计算,默认采用隐式转换。

  • 数组是一个可以存储多个数据类型的变量的容器

  • 动态初始化:创建数组的时候指定长度,系统自动赋值

  • 方法:程序中的独立功能,也是最小的执行单元

  • 栈内存:每个线程都有自己独立的栈,目前只要考虑一个即可,方法被调用进栈执行,执行完毕出栈

  • 堆内存:所有线程共享,存储对象,数组,字符串常量池,new关键字

  • 方法区:存储字节码信息

  • this:区分成员变量和局部变量,所在方法调用者的内存地址

  • 内存:所在方法调用者的地址值

  • static:静态变量,被该类所有对象共享

  • 静态变量是随着类的加载而加载的,优先于对象出现的

  • 静态方法只能访问静态变量和其他的静态方法

  • 非静态方法可以访问静态变量或者静态方法,也可以访问非静态的成员变量和非静态的成员方法

  • 静态方法中没有this关键字

  • 非静态方法要根据对象调用,静态方法随着类的加载而加载

  • 常量名大写,多个单词之间用下划线隔开

  • 枚举是一个特殊的Javabean类,这个类的对象是有限个

  • 面向对象的三大特征:封装继承多态

  • 子类能继承父类的非私有成员

  • private:只能本类访问

  • 缺省:当前类,同一个包

  • protected:本类,同一个包,子类

  • public:所有类访问

  • Object是所有类的祖宗类

  • 子类和父类中出现了重名的成员,用super指定访问父类。

  • 方法重写:当子类觉得父类中的某个方法不好用或者无法满足自己的需求时,可以重写一个方法名称、参数列表一样的方法,去覆盖父类的这个方法

  • 方法重写的校验注解@Override:要求方法名称和形参列表必须和重写方法一致

  • 子类重写父类方法时,访问权限必须大于或等于父类该方法的权限

  • 重写的方法返回值类型必须和被重写方法的返回值类型一致

  • 私有方法,静态方法不能被重写

  • 子类的全部构造器都会先调用父类的构造器,再执行自己

  • 任意类的构造器中,可以通过this()调用本类的兄弟构造器

  • 多态是在继承/实现情况下的一种现象,表现为:对象多态,行为多态

  • 多态:方法:编译看左,运行看右 成员变量:编译看左,运行看左

  • 多态的好处1:在多态形式下,右边对象是解耦合的,更便于扩展和维护

  • 多态的好处2:父类类型的变量作为参数,可以接受一个子类对象

  • 单例设计模式:确保某个类只能创建一个对象

  • 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类

  • 抽象类不能创建对象,仅作为一种特殊的父类,让子类继承并实现

  • 代码块是类的五大成分之一(成员变量,构造器,方法,代码块,内部类)

  • 外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称()

  • 有static修饰的内部类,属于外部类自己持有

  • 静态内部类中可以直接访问外部类的静态成员。

  • 静态内部类中不可以直接访问外部类的实例成员。

  • 匿名内部类是一种特殊的局部内部类,匿名指的是程序员不需要为这个类声明名字,默认有个隐藏的名字。

  • 匿名内部类本质是一个子类,同时会立即构建一个子类对象

  • 只有一个抽象方法的接口就是函数式接口,在接口上加上@FuncationalInterface注解

  • 集合是一种容器,用来装数据的,类似于数组,集合的大小可变

  • 泛型:定义类、接口、方法时,同时声明了一个或者多个类型变量

  • 通配符?可以在使用泛型时代表一切类型,ETKV是在定义泛型的时候使用

  • 泛型的上下限: ?extends E :表示?只能是E或者E的子类 ?super E :表示?只能是E或者E的父类

  • 泛型和集合不支持基本数据类型,只能支持对象类型(引用数据类型)

  • 泛型只存在编译期间

  • 包装类就是把基本类型的数据包装成对象的类型

    Collection集合特点

    List系列集合:添加的元素是有序、可重复、有索引
    • ArrayList(底层是基于数组存储数据的),LinekdList(底层是基于双链表存储数据的)
    Set系列集合:添加的元素是无序、不重复、无索引
    • HashSet:无序,不重复,无索引
    • LinkedHashSet:有序、不重复、无索引
    • TreeSet:按照大小默认升序排序、不重复、无索引

    Collection的遍历方式

    一:迭代器遍历
    迭代器是用来遍历集合的专用方式(数组没有迭代器)
    二:增强for循环
    for(元素的数据类型 变量名 :数组或者集合){}
    三:Lambda表达式
    default void forEach(Consumer<? super T> action)
    三种方式的区别:
    认识并发修改异常问题:遍历集合的同时又存在增删集合元素的行为时可能出现业务异常,这种现象被称之为并发修改异常问题
    • 增强for循环和Lambda遍历均不能解决并发修改异常问题,因此它们只适合做数据的遍历,不适合同时做增删操作。

    List集合的特有方法

    • List集合因为支持索引,所以多了很多与索引相关的方法,当然,Collection的功能List也都继承了。
    遍历方式:For循环,迭代器,增强for,lambda表达式

    哈希值:

    • 一个int类型的随机值,Java中每个对象都有一个哈希值
    • public int hashCode():返回对象的哈希码值
    HashSet集合:哈希表基于数组+链表+红黑树
    如果希望hashset认为内容一样是同一个对象,重写hashcode和equals方法

    LinkedHashSet的底层原理

    • 基于哈希表(数组,链表,红黑树)实现的,但是它的每个元素都额外的多了一个双链表的机制记录它前后元素的位置

    Map集合(双列)

    认识Map集合:
    • 键值对集合
    • 所有键是不允许重复的,但值可以重复,键和值是一一对应的,每一个键只能找到自己对应的值
    • 需要存储一一对应的数据时,可以考虑用map
    HashMap:无序,不重复,无索引
    LinkedHashMap:由键决定的特点:有序,不重复,无索引
    TreeMap:按照大小默认升序排序、不重复、无索引
    遍历方式:
    键找值:先获取Map集合全部的键,再通过遍历键来找值
    键值对:把键值对看成一个整体遍历
    Lambda:default void forEach(Biconsumer<? super K, ? super V> action)

    Stream流

    Stream流大量的结合了lambda的语法风格来编程,功能高效,代码简洁,可读性好。
    获取stream流的方式:
    获取集合的stream流
    • default Stream stream
    获取数组的stream流
    • public static Stream stream(T[] array)
    • public static Stream of(T…values)

    可变参数

    可以不传数据,可以传一个或者同时传多个数据给它,也可以传一个数组。eg. int…nums

    存储数据的方案

    • 文件可以长久保存
    • 文件在电脑磁盘中保存,即便断电或者程序终止,文件中的数据也不会丢失

    递归

    递归如果没有控制好终止,会出现递归死循环,导致栈内存溢出错误

    什么是框架?

    框架是一个预先写好的代码库或一组工具,旨在简化和加速开发过程

    多线程

    线程是一个程序内部的一条执行流程,多线程是指从软硬件上实现的多条执行流程的技术(多条线程由CPU负责调度执行)
    并发和并行同时进行:
    • 并发:CPU分时轮询的执行线程
    • 并行:同一时刻同时在执行
    创建线程:
    • 方式一:继承Thread类:编程比较简单但扩展性较差,不能继承其他的类,不能返回变成执行的结果
    • 方式二:实现Runnable接口:扩展性强,实现该接口的同时还可以继承其他的类,但编程相对复杂,不能返回线程执行的结果
    • 方式三:实现Callable接口,扩展性强,实现该接口的同时还可以继承其他的类,可以得到线程执行的结果,变成相对复杂

    线程池

    • 线程池是一个可以复用线程的技术
    创建线程池
    • 通过ExecutorService的实现类ThreadPoolExecutor自创建一个线程池对象
    • 使用Executors(线程池的工具类)调用方法返回不同特点的线程池对象

    网络通信三要素

    IP地址,端口,协议

    反射

    反射是加载类,并允许以编程的方式解剖类中的各种成分(成员变量,方法,构造器等)
    作用:
    基本作用:可以得到一个类的全部成分然后操作
    可以破坏封装性
    可以绕过泛型的约束
    最重要的用途是:适合做Java的框架,基本上,主流的框架都会基于反射设计出一些通用的功能

注解

作用:让其他程序根据注解信息来决定怎么执行该程序
注解本质上是一个接口
元注解:注解注解的注解

代理

newlProxyInstance方法在创建代理时,需要接几个参数,每个参数的含义是什么?
  • 参数一:用于执行用哪个类加载器去加载生成的代理类
  • 参数二:用于指定代理类需要实现的接口:明星类实现了哪些接口,代理类就实现哪些接口
  • 参数三:用于指定代理类需要如何去代理(代理要做的事情)

logback

记录日志

定义日志记录对象logger

事务

一组操作的集合,要么全部成功,要么全部失败

存储文件阿里云OSS

SpringAOP

面向切面编程,面向方面编程

需求:统计所有业务层方法的执行耗时
核心概念:
  • 连接点:JoinPoint,可以被AOP控制的方法(暗含方法执行时的相关信息)“
  • 通知:Advice,指那些 重复的逻辑,也就是共性功能(最终体现为一个方法)
  • 切入点:PointCut,匹配连接点的条件,通知仅会在切入点方法执行时被应用
  • 切面:Aspect,描述通知与切入点的对应关系(通知+切入点)
  • 目标对象:Target,通知所应用的对象

ThreadLocal

线程的局部变量,为每个线程提供单独一份存储空间,具有线程隔离的效果,不同的线程之间不会相互干扰

应用场景:在同一个线程/同一个请求中,进行数据共享

SpringBoot

外部配置优先级:命令行参数>java系统属性

外部>内部

内部配置优先级:properties>yml>yaml

推荐统一使用yml

Spring容器的bean

  • 默认是单例的

  • 单例的bean,默认是项目启动时实例化的(通过@Lazy可以延迟初始化)

  • bean的线程安全取决于bean的状态及bean的作用域

  • 单例bean:如果是无状态的bean,内部不保存任何状态信息,则是线程安全的

  • 单例bean:如果是有状态的bean,内部会保存状态信息,多个线程会同时操作该bean时,可能会出现数据 不一致的问题,这样的bean则是线程不安全的

  • 多例bean:每一次 请求都是一个全新的对象,所以线程安全