Java常见面试题-01-java基础

面向对象的特征

面向对象的特征:封装、继承、多态、抽象。

  • 封装:就是把对象的属性和行为(数据)结合为一个独立的整体,并尽可能隐藏对象的内部实现细节,就是把不想告诉或者不该告诉别人的东西隐藏起来,把可以告诉别人的东西公开,别人只能用我提供的功能实现需求,而不知道是如何实现的。增加安全性。
  • 继承:子类继承父类的数据属性和行为,并能根据自己的需求扩展出新的行为,提高了代码的复用性。
  • 多态:指允许不同的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式(发送消息就是函数调用)。封装和继承几乎都是为多态而准备的,在执行期间判断引用对象的实际类型,根据其实际的类型调用其相应的方法。
  • 抽象表示对问题领域进行分析、设计中得出的抽象的概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。在 Java 中抽象用 abstract 关键字来修饰,用 abstract修饰类时,此类就不能被实例化,从这里可以看出,抽象类(接口)就是为了继承而存在的。

Java 的基本数据类型有哪些

数据类型字节数位数
整型byte18
short216
int432
long864
浮点型float432
double864
布尔型boolean18
字符型char216

JDK、JRE、JVM 的区别

在这里插入图片描述

  • JDK(Java Development Kit)是整个 Java 的核心,是 java 开发工具包,包括了 Java 运行环境 JRE、Java 工具和 Java 基础类库。
  • JRE(Java Runtime Environment)是运行 JAVA 程序所必须的环境的集合,包含 java 虚拟机和 java 程序的一些核心类库。
  • JVM 是 Java Virtual Machine(Java 虚拟机)的缩写,是整个 java 实现跨平台的最核心的部分,能够运行以 Java 语言写作的软件程序。

重载和重写的区别

  • 重载: 发生在同一个类中,方法名必须相同,参数类型不同.个数不同.顺序不同, 方法返回值和访问修饰符可以不同,发生在编译时。
  • 重写: 发生在父子类中,方法名.参数列表必须相同,返回值范围小于等于父类, 抛出的异常范围小于等于父类,访问修饰符范围大于等于父类;如果父类方法访问修饰符为 private 则子类就不能重写该方法。

Java 中==和 equals 的区别

== 的作用:

  • 基本类型:比较的就是值是否相同
  • 引用类型:比较的就是地址值是否相同

equals 的作用:

  • 引用类型:默认情况下,比较的是地址值。(String、Integer、Date 这些类库中 equals 被重写,比较的是内容而不是地址!)

String、StringBuffer、StringBuilder 三者之间的区别

  • String 是字符串常量,String 类中使用 final 关键字修饰字符数组来保存字符串(private final char value[]) ,String 对象是不可变的,线程安全。如果要操作少量的数据用 String;
  • StringBuffer 字符串变量,StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。多线程字符串缓冲区下操作大量数据用 StringBuffer;
  • StringBuilder 字符串变量,StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的。单线程字符串缓冲区下操作大量数据用 StringBuilder。

注意: AbstractStringBuilder 是 StringBuilder 与 StringBuffer 的公共父类,定义了一些字符串的基本操作,如 expandCapacity()、append()、insert()、indexOf()e 等公共方法。

接口和抽象类的区别是什么

  • 实现:抽象类的子类使用 extends 来继承;接口必须使用 implements 来实现接口。
  • 构造函数:抽象类可以有构造函数;接口不能有。
  • main 方法:抽象类可以有 main 方法,并且我们能运行它;接口不能有 main 方法。
  • 实现数量:类可以实现很多个接口;但是只能继承一个抽象类。
  • 访问修饰符:接口中的方法默认使用 public 修饰;抽象类中的方法可以是任意访问修饰符

string 常用的方法有哪些

  • indexOf():返回指定字符的索引。
  • charAt():返回指定索引处的字符。
  • replace():字符串替换。
  • trim():去除字符串两端空白。
  • split():分割字符串,返回一个分割后的字符串数组。
  • getBytes():返回字符串的 byte 类型数组。
  • length():返回字符串长度。
  • toLowerCase():将字符串转成小写字母。
  • toUpperCase():将字符串转成大写字符。
  • substring():截取字符串。
  • equals():字符串比较。

什么是单例模式?有几种?

单例模式是指某个类的实例在多线程环境下只会被创建一次出来。单例模式有饿汉式单例模式、懒汉式单例模式和双检锁单例模式三种。

  • 饿汉式:线程安全,一开始就初始化。
    在这里插入图片描述

  • 懒汉式:非线程安全,延迟初始化。
    在这里插入图片描述

  • 双检锁:线程安全,延迟初始化。
    在这里插入图片描述

什么是反射,反射获取类对象的方式有哪些

在 Java 中的反射机制是指在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法;并且对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态调用对象方法的功能成为 Java 语言的反射机制。

获取 Class 对象的 3 种方法 :

  • 调用某个对象的 getClass()方法
  • 调用某个类的 class 属性来获取该类对应的 Class 对象
  • 使用 Class 类中的 forName()静态方法(最安全/性能最好)

jdk1.8 的新特性有哪些

  • Lambda 表达式:允许把函数作为一个方法的参数。
  • 方法引用: 允许直接引用已有 Java 类或对象的方法或构造方法。
  • 函数式接口:有且仅有一个抽象方法的接口叫做函数式接口,函数式接口可以被隐式转换为Lambda 表达式。
  • 接口允许定义默认方法和静态方法
  • Stream API: 把真正的函数式编程风格引入到 Java 中
  • 日期/时间类改进:java.time 包下,LocalDate/LocalTime/LocalDateTime。
  • Optional 类:Optional 类是一个可以为 null 的容器对象。如果值存在则 isPresent()方法会返回 true,调用 get()方法会返回该对象。
  • Java8 Base64 实现

Java 的异常

Throwable 是所有 Java 程序中错误处理的父类,有两种子类:Error 和Exception。

  • Error:表示由 JVM 所侦测到的无法预期的错误,由于这是属于 JVM 层次的严重错误,导致 JVM 无法继续执行,因此,这是不可捕捉到的,无法采取任何恢复的操作,顶多只能显示错误信息。
  • Exception:表示可恢复的例外,这是可捕捉到的。
    • 运行时异常:都是 RuntimeException 类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等, 这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。运行时异常的特点是Java 编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用 try-catch 语句捕获它,也没有用 throws 子句声明抛出它,也会编译通过。
    • 非运行时异常(编译异常):是 RuntimeException 以外的异常,类型上都属于 Exception 类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如 IOException、SQLException 等以及用户自定义的 Exception 异常,一般情况下不自定义检查异常。

常见的 RunTime 异常几种如下:

  • NullPointerException - 空指针引用异常
  • ClassCastException - 类型强制转换异常。
  • IllegalArgumentException - 传递非法参数异常。
  • ArithmeticException - 算术运算异常
  • ArrayStoreException - 向数组中存放与声明类型不兼容对象异常
  • IndexOutOfBoundsException - 下标越界异常
  • NegativeArraySizeException - 创建一个大小为负数的数组错误异常
  • NumberFormatException - 数字格式异常
  • SecurityException - 安全异常
  • UnsupportedOperationException - 不支持的操作异常

BIO、NIO、AIO 有什么区别?

  • BIO:Block IO 同步阻塞式 IO,就是我们平常使用的传统 IO,它的特点是模式简单使用方便,并发处理能力低。
  • NIO:New IO 同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过Channel(通道)通讯,实现了多路复用。
  • AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非堵塞 IO ,异步 IO 的操作基于事件和回调机制。

Threadloal 的原理

  • ThreadLocal:为共享变量在每个线程中创建一个副本,每个线程都可以访问自己内部的副本变量。通过 threadlocal 保证线程的安全性。
  • 在 ThreadLocal 类中有一个静态内部类 ThreadLocalMap(其类似于 Map), 用键值对的形式存储每一个线程的变量副本,ThreadLocalMap 中元素的 key 为当前ThreadLocal 对象,而 value 对应线程的变量副本。ThreadLocal 本身并不存储值,它只是作为一个 key 保存到 ThreadLocalMap 中,但是这里要注意的是它作为一个 key 用的是弱引用,因为没有强引用链,弱引用可能会被GC 回收。这样就会在 ThreadLocalMap 中存在一些 key 为 null 的键值对(Entry)。因为 key 变成 null 了,我们是没法访问这些键值对( Entry) 的,但是这些键值对(Entry) 本身是不会被清除的。如果没有手动删除对应 key 就会导致这块内存不会被回收也无法访问,也就是内存泄漏。
  • 使用完 ThreadLocal 之后,记得调用 remove 方法。 在不使用线程池的前提下, 即使不调用 remove 方法,线程的"变量副本"也会被 gc 回收,即不会造成内存泄漏的情况。

同步锁、死锁、乐观锁、悲观锁分别是什么意思

  • 同步锁:当多个线程同时访问同一个数据时,很容易出现问题。为了避免这种情况出现,我们要保证线程同步互斥,就是指并发执行的多个线程,在同一时间内只允许一个线程访问共享数据。Java 中可以使用 synchronized 关键字来取得一个对象的同步锁。
  • 死锁:就是多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。
  • 乐观锁:总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS 算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于 write_conditio 机制,其实就是提供的乐观锁。在 Java 中 java.util.concurrent.atomic 包下面的原子变量类就是使用了乐观锁的一种实现方式 CAS 实现的。
  • 悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java 中synchronized 和 ReentrantLock 等独占锁就是悲观锁思想的实现。

synchronized 底层实现原理?

  • synchronized 可以保证方法或者代码块在运行时,同一时刻只有一个方法可以进入到临界区,同时它还可以保证共享变量的内存可见性。Java 中每一个对象都可以作为锁,这是 synchronized 实现同步的基础。
    • 普通同步方法,锁是当前实例对象
    • 静态同步方法,锁是当前类的 class 对象
    • 同步方法块,锁是括号里面的对象

synchronized 和 volatile 的区别是什么?

  • volatile 本质是在告诉 jvm 当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取; synchronized 则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。
  • volatile 仅能使用在变量级别;synchronized 则可以使用在变量、方法、和类级别的。
  • volatile 仅能实现变量的修改可见性,不能保证原子性;而 synchronized 则可以保证变量的修改可见性和原子性。
  • volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞。
  • volatile 标记的变量不会被编译器优化;synchronized 标记的变量可以被编译器优化。

synchronized 和 Lock 有什么区别?

  • 首先 synchronized 是 java 内置关键字,在 jvm 层面,Lock 是个 java 类;
  • synchronized 无法判断是否获取锁,Lock 可以判断是否获取到锁;
  • synchronized 会自动释放锁,Lock 需在 finally 中通过unlock()方法手工释放锁,否则容易造成线程死锁;
  • 用 synchronized 关键字修饰的线程 1 和线程 2,如果当前线程 1 获得锁,线程 2 就会进入等待状态。如果线程 1 阻塞,线程 2 则会一直等待下去,而 Lock 锁就不一定会一直等待下去,如果尝试获取不到锁,线程就可以直接结束了;
  • synchronized 的锁可重入、不可中断、非公平,而 Lock 锁可重入、可中断、可公平;
  • synchronized 锁适合少量代码的同步问题,Lock 锁适合大量代码的同步问题。

冒泡排序

public class Main {
    public static void main(String[] args) {
        int arr[] = {10, 6, 9, 4, 7, 8, 1, 2, 5, 3};
        int temp;
        for (int i = 0; i < arr.length - 1; i++) { //  只需要将前9个数据进行排列,如果说前9个数据都排列好了,那么最后一个数据的位置也就是正确的
            for (int j = 0; j < arr.length - i - 1; j++) { // 遍历集合就是如果说已经排列好了一个数据的话,我们就不需要进行重复的排列了
                if (arr[j] > arr[j + 1]) {  // 如果前一个数据大于后一个数据的话,那么就进行交换
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }

        for (int i : arr) {
            System.out.print(i + " ");
        }
    }
}

Java语言有哪些特点

  • 简单易学、有丰富的类库
  • 面向对象(Java最重要的特性,让程序耦合度更低,内聚性更高)
  • 与平台无关性(JVM是Java跨平台使用的根本)
  • 可靠安全
  • 支持多线程

面向对象和面向过程的区别

  • 面向过程:是分析解决问题的步骤,然后用函数把这些步骤一步一步地实现,然后在使用的时候一一调用则可。性能较高,所以单片机、嵌入式开发等一般采用面向过程开发。
  • 面向对象:是把构成问题的事务分解成各个对象,而建立对象的目的也不是为了完成一个个步骤,而是为了描述某个事物在解决整个问题的过程中所发生的行为。面向对象有封装继承多态的特性,所以易维护易复用易扩展。可以设计出低耦合的系统。 但是性能上来说,比面向过程要低。

标识符的命名规则

命名规则:(硬性要求)

  • 标识符可以包含英文字母,0-9的数字,$以及_
  • 标识符不能以数字开头
  • 标识符不是关键字

命名规范:(非硬性要求)

  • 类名规范:首字符大写,后面每个单词首字母大写(大驼峰式)。
  • 变量名规范:首字母小写,后面每个单词首字母大写(小驼峰式)。
  • 方法名规范:同变量名。

instanceof 关键字的作用

instanceof 严格来说是Java中的一个双目运算符,用来测试一个对象是否为一个类的实例。
用法:

boolean result = obj instanceof Class

其中 obj 为一个对象,Class 表示一个类或者一个接口,当 obj 为 Class 的对象,或者是其直接或
间接子类,或者是其接口的实现类,结果result 都返回 true,否则返回false。

Java自动装箱与拆箱

  • 自动装箱就是自动将基本数据类型转换为包装器类型(int–>Integer);调用方法:Integer的
    valueOf(int) 方法。
  • 自动拆箱就是自动将包装器类型转换为基本数据类型(Integer–>int)。调用方法:Integer的intValue方

以下代码会输出什么?

public class Main {
	public static void main(String[] args) {
		Integer i1 = 100;
		Integer i2 = 100;
		Integer i3 = 200;
		Integer i4 = 200;
		System.out.println(i1==i2);
		System.out.println(i3==i4);
	}
}
true
false

在通过valueOf方法创建Integer对象的时候,如果数值在[-128,127]之间,便返回指向IntegerCache.cache中已经存在的对象的引用;否则创建一个新的Integer对象。上面的代码中i1和i2的数值为100,因此会直接从cache中取已经存在的对象,所以i1和i2指向的是同一个对象,而i3和i4则是分别指向不同的对象。

Hashcode的作用

  • java的集合有两类,一类是List,还有一类是Set。前者有序可重复,后者无序不重复。当我们在set中
    插入的时候怎么判断是否已经存在该元素呢,可以通过equals方法。但是如果元素太多,用这样的方法
    就会比较慢。
  • 于是有人发明了哈希算法来提高集合中查找元素的效率。 这种方式将集合分成若干个存储区域,每个对象可以计算出一个哈希码,可以将哈希码分组,每组分别对应某个存储区域,根据一个对象的哈希码就可以确定该对象应该存储的那个区域。
  • hashCode方法可以这样理解:它返回的就是根据对象的内存地址换算出的一个值。这样以来,当集合
    要添加新的元素时,先调用这个元素的hashCode方法,就一下子能定位到它应该放置的物理位置上。
    如果这个位置上没有元素,它就可以直接存储在这个位置上,不用再进行任何比较了;如果这个位置上
    已经有元素了,就调用它的equals方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地
    址。这样以来实际调用equals方法的次数就大大降低了,几乎只需要一两次。

Collection包结构,与Collections的区别

  • Collection是集合类的上级接口,子接口有 Set、List;
  • Collections是集合类的一个帮助类, 它包含有各种有关集合操作的静态方法,用于实现对各种集合的搜索、排序、线程安全化等操作。此类不能实例化,就像一个工具类,服务于Java的Collection框架。

Java的四种引用,强弱软虚

  • 强引用(强引用是平常中使用最多的引用,强引用在程序内存不足(OOM)的时候也不会被回收,使用方式如下)
String str = new String("str");
  • 软引用(软引用在程序内存不足时,会被回收,使用方式如下)
// 注意:wrf这个引用也是强引用,它是指向SoftReference这个对象的,
// 这里的软引用指的是指向new String("str")的引用,也就是SoftReference类中T
SoftReference<String> wrf = new SoftReference<String>(new String("str"));
  • 弱引用(弱引用就是只要JVM垃圾回收器发现了它,就会将之回收,使用方式如下)
WeakReference<String> wrf = new WeakReference<String>(str);
  • 虚引用(虚引用的回收机制跟弱引用差不多,但是它被回收之前,会被放入 ReferenceQueue 中。注意
    哦,其它引用是被JVM回收后才被传入 ReferenceQueue 中的。)

Java创建对象有几种方式?

  • new创建新对象
  • 通过反射机制
  • 采用clone机制
  • 通过序列化机制

有没有可能两个不相等的对象有相同的hashcode

有可能.在产生hash冲突时,两个不相等的对象就会有相同的 hashcode 值.当hash冲突产生时,一般有以
下几种方式来处理:

  • 拉链法:每个哈希表节点都有一个next指针,多个哈希表节点可以用next指针构成一个单向链表,被
    分配到同一个索引上的多个节点可以用这个单向链表进行存储。
  • 开放定址法:一旦发生了冲突,就去寻找下一个空的散列地址,只要散列表足够大,空的散列地址总能找
    到,并将记录存入。
  • 再哈希:又叫双哈希法,有多个不同的Hash函数.当发生冲突时,使用第二个,第三个….等哈希函数计算
    地址,直到无冲突。

深拷贝和浅拷贝的区别是什么?

  • 浅拷贝:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向
    原来的对象.换言之,浅拷贝仅仅复制所考虑的对象,而不复制它所引用的对象.
  • 深拷贝:被复制对象的所有变量都含有与原来的对象相同的值.而那些引用其他对象的变量将指向被
    复制过的新对象.而不再是原有的那些被引用的对象.换言之.深拷贝把要复制的对象所引用的对象都
    复制了一遍.

final有哪些用法?

  • 被final修饰的类不可以被继承
  • 被final修饰的方法不可以被重写,被final修饰的方法,JVM会尝试将其内联,以提高运行效率
  • 被final修饰的变量不可以被改变.如果修饰引用,那么表示引用不可变,引用指向的内容可变.
  • 被final修饰的常量,在编译阶段会存入常量池中.

static都有哪些用法?

  • 定义静态变量
  • 定义静态方法
  • 静态代码块,多用于初始化操作
  • 修饰内部类,称之为静态内部类
  • 静态导包,可以用来指定导入某个类中的静态资源,并且不需要使用类名,可以直接使用资源名

3*0.1 == 0.3返回值是什么?

false,因为有些浮点数不能完全精确的表示出来。

a=a+b与a+=b有什么区别吗?

+= 操作符会进行隐式自动类型转换,此处a+=b隐式的将加操作的结果类型强制转换为持有结果的类型,
而a=a+b则不会自动进行类型转换

try catch finally,try里有return,finally还执行么?

执行,并且finally的执行早于try里面的return。

  • 不管有没有出现异常,finally块中代码都会执行;
  • 当try和catch中有return时,finally仍然会执行;
  • finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保
    存起来,管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在finally执行前确定的;
  • finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。

OOM你遇到过哪些情况,SOF你遇到过哪些情况

OOM:

  1. OutOfMemoryError异常
    除了程序计数器外,虚拟机内存的其他几个运行时区域都有发生OutOfMemoryError(OOM)异常的可能。
    Java Heap 溢出:
    一般的异常信息:java.lang.OutOfMemoryError:Java heap spacess。
    java堆用于存储对象实例,我们只要不断的创建对象,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制清除这些对象,就会在对象数量达到最大堆容量限制后产生内存溢出异常。出现这种异常,一般手段是先通过内存映像分析工具(如Eclipse Memory Analyzer)对dump出来的堆转存快照进行分析,重点是确认内存中的对象是否是必要的,先分清是因为内存泄漏(Memory Leak)还是内存溢出(Memory Overflow)。如果是内存泄漏,可进一步通过工具查看泄漏对象到GCRoots的引用链。于是就能找到泄漏对象是通过怎样的路径与GC Roots相关联并导致垃圾收集器无法自动回收。如果不存在泄漏,那就应该检查虚拟机的参数(-Xmx与-Xms)的设置是否适当。
  2. 虚拟机栈和本地方法栈溢出
    如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常。如果虚拟机在扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常,这里需要注意当栈的大小越大可分配的线程数就越少。
  3. 运行时常量池溢出
    异常信息:java.lang.OutOfMemoryError:PermGenspace
    如果要向运行时常量池中添加内容,最简单的做法就是使用String.intern()这个Native方法。该方法的作用是:如果池中已经包含一个等于此String的字符串,则返回代表池中这个字符串的String对象;否则,将此String对象包含的字符串添加到常量池中,并且返回此String对象的引用。由于常量池分配在方法区内,我们可以通过-XX:PermSize和-XX:MaxPermSize限制方法区的大小,从而间接限制其中常量池的容量。
  4. 方法区溢出
    方法区用于存放Class的相关信息,如类名、访问修饰符、常量池、字段描述、方法描述等。也有可能是方法区中保存的class对象没有被及时回收掉或者class信息占用的内存超过了我们配置。
    异常信息:java.lang.OutOfMemoryError:PermGenspace方法区溢出也是一种常见的内存溢出异常,一个类如果要被垃圾收集器回收,判定条件是很苛刻的。在经常动态生成大量Class的应用中,要特别注意这点。
    SOF(堆栈溢出StackOverflow)
    StackOverflowError 的定义:当应用程序递归太深而发生堆栈溢出时,抛出该错误。因为栈一般默认为1-2m,一旦出现死循环或者是大量的递归调用,在不断的压栈过程中,造成栈容量超过1m而导致溢出。
    栈溢出的原因:递归调用,大量循环或死循环,全局变量是否过多,数组、List、map数据过大。

简述线程、程序、进程的基本概念。以及他们之间关系是什么?

  • 线程与进程相似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线
    程。与进程不同的是,同类的多个线程共享同一块内存空间和一组系统资源,所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。
  • 程序是含有指令和数据的文件,被存储在磁盘或其他的数据存储设备中,也就是说程序是静态的代码。进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。简单来说,一个进程就是一个执行中的程序,它在计算机中一个指令接着一个指令地执行着,同时,每个进程还占有某些系统资源如 CPU 时间,内存空间,文件,输入输出设备的使用权等等。换句话说,当程序在执行时,将会被操作系统载入内存中。
  • 线程是进程划分成的更小的运行单位。线程和进程最大的不同在于基本上各进程是独立的,而各线程则不一定,因为同一进程中的线程极有可能会相互影响。从另一角度来说,进程属于操作系统的范畴,主要是同一段时间内,可以同时执行一个以上的程序,而线程则是在同一程序内几乎同时执行一个以上的程序段。

欢迎java热爱者了解文章,作者将会持续更新中,期待各位友友的关注和收藏。。。

  • 26
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿胡爱编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值