JavaSE 复习大纲

本文详细介绍了Java编程的基础知识,包括数据类型、运算符、逻辑控制结构以及重载与重写的概念。深入探讨了抽象类与接口的异同,强调了线程与进程的区别,展示了创建线程的不同方式,并分析了Runnable与Callable接口以及Thread类的区别。此外,还讨论了线程安全问题,包括锁的设计、死锁的避免以及确保线程安全的方法。最后,简要提到了JVM内存划分和垃圾回收机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、数据类型

  1. 基本数据类型
  2. String

三、运算符

  1. 算术运算符(+、-、*、/)
  2. 关系运算符(==、!=、>、<、>=、<=)
  3. 逻辑运算符(&&、||、!)
  4. 位运算符(&、|、~、^)
  5. 移位运算符(<<、>>、>>>)
  6. 条件运算符/三目运算符(表达式 1 ? 表达式2 : 表达式3)

四、逻辑控制

  1. 顺序结构
  2. 分支结构(if,switch)
  3. 循环结构(while、for、foreach、do while)

五、重载与重写

在这里插入图片描述

六、抽象类和接口

  1. super 和 this
    在这里插入图片描述
  2. 抽象类和接口的异同

相同

  • 抽象类和接口都不能实例化

不同

  • 构造方法:抽象类可以有构造方法;接口没有
  • 成员方法:抽象类可以是抽象的,也可以是非抽象的;(jdk1.8 之后)接口成员方法可以是 default 或者 static 开头
  • 成员变量:抽象类可以是变量也可以是常量;接口只能是常量,默认修饰符是 public static final

七、进程与线程

  1. 并行与并发
    并行: 例如一台电脑有 8 个 cpu,可以同时执行 8 个程序
    并发: 从微观角度看,并发是串行的,执行完当前进程,再执行下一个进程;从宏观角度看,并发是并行的,因为每个进程执行的时间都很快,可以理解为并行。

虽然并行与并发概念并不一样,但是一般都用并发代指并行+并发

  1. 用户态和内核态
    内核态:操作系统内核执行任务,一旦某个任务进入内核态执行,就变得不可控,往往意味着比较低效;
    用户态:应用程序执行任务

  2. 进程与线程的区别
    a. 进程包含线程,一个进程可以有多个线程
    b. 进程是资源分配的基本单位,线程是系统调度的基本单位。也就是说,进程得到一部分资源后,一个或者多个线程共享这部分资源
    c. 进程与进程之间是相互独立的,一个进程挂掉之后不会影响另外一个进程;但是线程不一样,线程共享进程申请的资源,如果一个线程挂了,可能影响另外一个线程,以至于危害到整个进程
    d. 进程是资源分配的最小单位,线程是调度执行的最小单位。

  3. 创建线程的方式
    a. 继承 Thread 类重写 run 方法
    b. 实现 Runnable 接口重写 run 方法,实例化实现接口的类,然后将引用传递给 Thread 实例化对象

 Runnable r2 = new Create2();
        Thread c2 = new Thread(r2);
        c2.start();

c. 匿名内部类,实际上还是继承 Thread 类

        Thread c3 = new Thread() {
            @Override
            public void run() {
                System.out.println("匿名内部类创建");
            }
        };
        c3.start();

d. lambda 表达式创建

        Thread c4 = new Thread(() ->
                System.out.println("lambda 表达式创建"));
        c4.start();

e. Callable 接口创建

class Create5 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // Callable 泛型参数与下面返回值的类型相同
        Callable<Object> callable = new Callable<Object>() {
            @Override
            public Integer call() throws Exception {
            	// doSomething
                System.out.println("Callable 创建线程");
                return null;
            }
        };

        // 使用 FutureTask 把 Callable 包裹起来, 传 task 对象给 Thread
        // FutureTask 起到的作用就是 "未来能获取到一个结果"
        // 也就是 Callable 重写方法中执行的结果
        FutureTask<Object> task = new FutureTask<>(callable);
        Thread thread = new Thread(task);
        thread.start();

        // 通过 FutureTask 的 get 方法获取到结果
        // 如果线程阻塞, 对应的线程没有执行完, get 就等待阻塞
        Integer res = (Integer) task.get();
    }
}
  1. Runnable 和 Callable 的区别
    a. Runnable 和 Callable 中都只有一个重写方法,Runnable 是 run 方法,Callable 是 call 方法
    b. run 方法没有返回值,不抛异常;call 方法有返回值,抛异常
    c. 使用 Callable 创建线程需要使用 FutureTask 类来接受返回结果,Runnable 不用

  2. Thread 和 Runnable 的区别
    本质上没有区别
    a.Runnable 和 Thread 创建线程的方式不一样
    b.Runnable 是接口,Thread 是实体类,Thread 实现了 Runnable 接口
    c. 如果是复杂的工作,使用 Thread,简单的使用 Runnable

  3. wait 和 sleep 的区别
    a. wait 使用之前需要请求锁,也就是等待锁释放;sleep 无视锁的状态
    b. wait 是 Object 的方法;sleep 是 Thread 的静态方法

  4. 单例模式
    a. 懒汉模式
    b. 饿汉模式

  5. 线程安全

首先我们要了解线程不安全的根本原因是线程的抢占式执行
保证线程安全的方法

  • 保证原子性
  • 内存可见性
  • 禁止指令重排序

synchronized 能保证线程安全
而 volatile 不能保证原子性

  1. 锁的设计
  1. 死锁
    产生死锁的原因
  • 互斥条件:一个资源每次只能被一个进程使用
  • 请求与保存条件:一个进程因请求支援而阻塞时,对已得到的资源不释放
  • 不剥夺条件:进程已获得的资源,在使用完之前,不能强行剥夺
  • 循环等待条件:若干个进程之间形成一种头尾相接的循环等待资源关系

解决的办法

  • 不要再加锁的代码中尝试获取其他锁
  • 约定顺序加锁
  1. CAS 与自旋锁

  2. JUC (Java.util.concurrent)

九、JVM

  1. 什么是 JVM
  2. JDK、JRE、JVM
  3. JVM 内存划分
  4. JVM 的作用
  5. 双亲委派模型
  6. 垃圾回收
  7. 回收算法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值