计算机考研失败,准备零基础学Java混口吃的(持续更新)

沉淀

我承认我是个废物
会重点记录一些自己之前没了解过的内容,或者觉得比较重要的内容

JAVA基础

  • 枚举类

说实话写了那么久的代码,一直没用过枚举类型,因此也没有了解过,趁现在了解一下罢!

  1. 为什么要使用枚举?
    使用枚举的地方会有更强的类型约束,编译器会帮助检查入参类型,规避潜在风险
public class Enum {
  // 在我们常常会这样定义一些常变量,但这样定义会产生一定的风险
  public static final Integer NORMAL = 0;
  public static final Integer LOCKED = 1;
  public static final Integer DISABLE = 2;

  @Test
  public void main() {
    handleState(NOMAL);  // 正常执行
    handleState(Interger.MAX_VALUE);  // 随便输入一个数字,依旧可以正常执行,但是结果可能不是你想要的
    handleStateEnum(Integer.MAX_VALUE);  //编译器报错
    handleStateEnum(UserState.LOCKED);  // 正常执行
  }

  public handleState(Integer state) {
    if(state == NORMAL) System.out.print("Hello, World!");
  }

  public handleStateEnum(UserState userState) {
    if(state == UserState.NORMAL) System.out.print("Hello, World!");
  }
}

enum UserState {
  // 同时还可以对这些成员变量赋予一些值,实际生产中也可能使用到
  NORMAL(0, "员工"),
  LOCKED(1, "管理员"),
  DISABLE(2, "编外人员");
  private long id;
  private String name;
}

Java的集合框架

  • Java 容器分为 CollectionMap 两大类,其下又有很多子类,如下所示:
    Collection包括:List、ArrayList、LinkedList、Vector、Stack、Set、HashSet、LinkedHashSet、TreeSet
    Map包括:HashMap、LinkedHashMap、TreeMap、ConcurrentHashMap、Hashtable

Collection 和 Collections 有什么区别?

  • 区别如下:
    Collection 是一个集合接口,它提供了对集合对象进行基本操作的通用接口方法,所有集合都是它的子类,比如 List、Set 等。
    Collections 是一个包装类,包含了很多静态方法,不能被实例化,就像一个工具类,比如提供的排序方法:Collections. sort(list)。

List、Set、Map 之间的区别是什么?

  • List、Set、Map 的区别主要体现在两个方面:元素是否有序、是否允许元素重复。

太多了记不过来了,以后有时间再说了

  • ArrayList

  • 初始化
    底层数组名叫elementData,
    1.初始大小是0;
    2.当有数据插入时,默认大小DEFAULT_CAPACITY = 10;
    3.如果在创建ArrayList时指定了initialCapacity,则初始大小是initialCapacity。
  • 扩容机制
    每次调用add()方法都会将数组需要的最小容量:minCapacity(size+1)与oldCapacity=elementData.length之间大小进行比较,如果minCapacity更大,则说明需要扩容。
    1.实现关键:扩容核心方法是grow()方法。
   /**
     * ArrayList扩容的核心方法。
     */
    private void grow(int minCapacity) {
        // oldCapacity为旧容量,newCapacity为新容量
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        //然后检查新容量是否大于最小需要容量,若还是小于最小需要容量,那么就把最小需要容量当作数组的新容量,
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        // MAX_ARRAY_SIZE 为 `Integer.MAX_VALUE - 8`。
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
  • 多线程编程

  • 线程的生命周期
    ①新建状态;
    ②就绪状态:当线程对象调用了start()方法之后,该线程就进入就绪状态;
    ③运行状态:如果就绪状态的线程获取 CPU 资源,就可以执行 run(),此时线程便处于运行状态;
    ④阻塞状态:如果一个线程执行了sleep(睡眠)、suspend(挂起)等方法,失去所占用资源之后,该线程就从运行状态进入阻塞状态。;
    ⑤死亡状态:一个运行状态的线程完成任务或者其他终止条件发生时,该线程就切换到终止状态。
  • 创建线程方法
    1.实现Runnable接口;
    2.继承Thread;
    3.通过Callable创建线程;
    4.通过线程池。
  1. 继承Thread类
public class MyThread extends Thread {

  @Override
  public void run() {
    System.out.println("MyThread...run...");
  }

  public static void main(String[] args) {
    // 创建MyThread对象
    MyThread t1 = new MyThread();
    MyThread t2 = new MyThread();

    // 调用start方法启动线程,调用一次就是启动一个;
    t1.start();
    t2.start();
  }
}

Tomcat部署Javaweb应用

  • 安装Tomcat

    1. 官网下载并解压缩文件
    1. 目录结构
      bin目录:存放各个平台(操作系统)下启动和停止Tomcat服务的脚本文件如stratup.bat:windows平台下;startup.sh:linux平台下的启动脚本文件;
      conf目录:存放各种Tomcat服务器的配置文件。server.xml文件里可以配置端口,默认端口8080。

      lib目录:存放Tomcat服务器所需要的jar。
      log目录:存放Tomcat服务运行的日志。
      temp目录:存放Tomcat运行时的临时文件。
      webapps:存放允许客户端访问的资源。
      work:存放Tomcat将JSP转换之后的Servlet文件。
    1. idea中配置Tomcat

Spring项目学习

  • 点赞模块

  • 数据库表设计:
字段名称 数据类型 注释
id BIGINT 主键id
user_id BIGINT 用户id
biz_id BIGINT 点赞的业务id
creat_time DATETIME 创建时间
update_time DATETIME 更新时间

①如果是进行点赞业务,先使用user_id和biz_id查找有没有点过赞,如果点过就返回false,如果没有点过赞就加入表中
②如果是进行取消赞业务,先使用user_id和biz_id查找有没有点过赞,如果没有点过则返回false,如果点过就删除点赞记录
③使用biz_id查找该业务的总点赞数,并返回
项目改进:DB操作次数过多,性能不高,所以①②③改操作redis,并使用定时任务更新数据库。

  • 点赞的数据结构设计:

    使用set结构存储业务的点赞信息
    ①当进行点赞时,如果redis中存在则返回false,如果不存在则往redis中插入数据
    ②当进行取消赞时,如果redis中不存在则返回false,如果存在则删除相应的userId。
  • 点赞总数的数据结构设计

    使用zset存储点赞总数信息,其中value是业务id——biz_id,分值是该业务的点赞总数
    ①在点赞的set中获取点赞总数,并存储到redis中
    ②使用定时任务——SpringTask框架,在启动类中加上@EnableScheduling注解后再在使用定时任务的方法上使用@Scheduled(fixedDelay = 20000),实习每20s的定时任务。

八股文

听说八股也要背一背,那就背一背吧。这个主要是看b站上的黑马视频的。话说我记这个干嘛,简单写一写得了。

  • JVM

  • JVM的组成

JVM是JAVA程序的运行环境(java二进制字节码的运行环境)
好处:①一次编写到处运行;②自动内存管理,垃圾回收

  • 什么是程序计数器

线程私有的,每个线程一份,内部保存的字节码的行号。用于记录正在执行的字节码指令的地址。

  • 请详细介绍JAVA堆

  • 线程共享的区域:主要用来保存对象实例,数组等,内存不够则抛出OutOfMemoryError异常

  • Redis

  • 缓存

    1. 击穿:当某一key过期且Redis还未来得及重建时,此时数据查询等是直接通过数据库进行的,所以这时如果有大量的对此key的并发请求时,有可能会把数据库压垮。
      解决方案:①互斥锁:当某一线程在Redis中未命中时,就申请互斥锁,并重建缓存
           ②逻辑过期:Redis中不设置过期时间,在数据中加一条“逻辑时间”字段。当“逻辑时间”过期,线程会新开一个线程进
           行缓存重建,同时返回数据。也就是说在重建没有完成时,返回的都是“过期数据”,这样保证了高可用。
    1. 穿透:查询一条不存在的数据,数据库查询不到数据也不会写如内存,导致每次查询都会请求数据库
      解决方案:使用布隆过滤器。布隆过滤器主要使用位图和哈希函数实现。
    1. 雪崩:有大量key同时失效或Redis宕机,导致大量请求到达数据库,带来巨大压力
      解决方案:①设置随机的TTL过期时间②利用Redis集群提高服务的可用性③给缓存业务添加④添加多级缓存
  • 双写一致

修改数据库数据后缓存数据也要保持一致

    1. 应用场景:实时性要求不高的文章热点数据,允许延时一致。
      解决方案:采用异步通知。使用MQ中间件,更新数据之后,通知缓存删除。
  • Redis持久化
    1. RDB:简单来说就是把内存中的所有数据记录到磁盘中。当Redis实例故障重启后,从磁盘读取快照文件,恢复数据。
      RDB触发机制:可以在redis.conf文件中找到,格式如下:
      其中bgsave:bgsave开始时会fork主进程得到子进程,子进程共享主进程的内存数据。完成fork后读取内存数据并写入RDB文件
# 900秒内至少有一个1个key被修改,则执行bgsave
save 900 1

    1. AOF:Redis处理的每一个写命令都会记录在AOF中,可以看做是命令日志文件。
  • 过期策略
    1. 惰性删除:访问key的时候判断是否过期,若过期则删除
    1. 定期删除:每隔一段时间,就对一些key进行检查,并删除过期的key
      模式:①SLOW模式:SLOW是定时任务②FAST模式:执行频率不固定。
posted @ 2024-03-06 19:16  这有懒狗233  阅读(5)  评论(0编辑  收藏  举报