进程、线程、协程区别:
1、进程
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。每个进程都有自己的独立内存空间,不同进程通过进程间通信来通信。由于进程比较重量,占据独立的内存,所以上下文进程间的切换开销(栈、寄存器、虚拟内存、文件句柄等)比较大,但相对比较稳定安全。
2、线程
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。线程间通信主要通过共享内存,上下文切换很快,资源开销较少,但相比进程不够稳定容易丢失数据。
3、协程
协程是一种用户态的轻量级线程,协程的调度完全由用户控制。协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈,直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快。
进程多与线程比较
线程是指进程内的一个执行单元,也是进程内的可调度实体。线程与进程的区别:
1) 地址空间:线程是进程内的一个执行单元,进程内至少有一个线程,它们共享进程的地址空间,而进程有自己独立的地址空间
2) 资源拥有:进程是资源分配和拥有的单位,同一个进程内的线程共享进程的资源
3) 线程是处理器调度的基本单位,但进程不是
4) 二者均可并发执行
5) 每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口,但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制
协程多与线程进行比较
1) 一个线程可以多个协程,一个进程也可以单独拥有多个协程,这样python中则能使用多核CPU。
2) 线程进程都是同步机制,而协程则是异步
3) 协程能保留上一次调用时的状态,每次过程重入时,就相当于进入上一次调用的状态
静态代理和动态代理的区别?
静态代理:是在java文件编译前,手动写好代理类对象。这样只能代理一类对象,即一类接口的类型。
动态代理:是通过反射原理,在程序运行的时候动态的生成的代理对象,所以可以代理任意的类对象。
Cglib和jdk动态代理的区别?
1、Jdk动态代理:利用拦截器(必须实现InvocationHandler)加上反射机制生成一个代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理
2、 Cglib动态代理:利用ASM框架,对代理对象类生成的class文件加载进来,通过修改其字节码生成子类来处理(通过ASM框架生成字节码变相执行Java代码,在JVM中程序执行不一定非要写java代码,只要能生成java字节码,jvm并不关心字节码的来源)
Integer实现原理及其缓存机制?
Integer是int基本数据类型的包装类,无非是在int基本类型的基础上增加了一些操作和其他属性。
Integer的实际对应int值是通过intValue()方法获取的,源码如下:
private final int value;//对应int基本类型的数值 是一个常量整型
public int intValue() {
return value;
}
装箱用到的一个方法是valueOf(),让我们看看源码:
//可以看到传入的i 先和IntegerCache比较 在IntegerCache中则返回IntegerCache中的Integer不存在则new一个Integer对象
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
IntegerCache实现如下:
//IntegerCache是个Integer的内部类,在类加载的时候创建了256个缓存Integer对象,范围-128至127
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
所以我们用interger去比较得时候不要用==(直接==得话,假如缓存中不存在,那么就会new一个integer出来,就不相等了) 而用quals比较好,equals做了拆箱动作,相当于先intvalue 再==比较。。。
wait和yeild区别?
①sleep方法给其他线程运行机会时不考虑线程的优先级,因此会给低线程优先级运行的机会,而yield方法只会给相同优先级或者更高优先级线程运行的机会
②线程执行sleep()方法后转入阻塞状态,所以,执行sleep()方法的线程在指定的时间内不会被执行,而yield()方法只是使当前线程重新回到可执行状态,所以执行yield()方法的线程可能在进入可执行状态后马上又被执行
③sleep()方法声明抛出InterruptedException,而yield()方法没有声明任何异常
④sleep()方法比yield()方法(跟操作系统相关)有更好的可移植性
wait 和sleep区别?
1、sleep是线程中的方法,但是wait是Object中的方法。
2、sleep方法不会释放lock,但是wait会释放,而且会加入到等待队列中。
3、sleep方法不依赖于同步器synchronized,但是wait需要依赖synchronized关键字。
4、sleep不需要被唤醒(休眠之后推出阻塞),但是wait需要(不指定时间需要被别人中断)。
String,StringBuffer与StringBuilder的区别?
String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,这样不仅效率低下,而且大量浪费有限的内存空间
StringBuild是线程不安全的,但是速度快
StringBuffer是线程安全的,但是速度慢
类的实例化顺序?
1. 父类静态成员和静态初始化块 ,按在代码中出现的顺序依次执行
2. 子类静态成员和静态初始化块 ,按在代码中出现的顺序依次执行
3. 父类实例成员和实例初始化块 ,按在代码中出现的顺序依次执行
4. 父类构造方法
5. 子类实例成员和实例初始化块 ,按在代码中出现的顺序依次执行
6. 子类构造方法
有没有有顺序的 Map 实现类,如果有,他们是怎么保证有序的?
LinkedHashMap 使用双向链表的形式来维护插入顺序。。
反射的原理,反射创建类实例的三种方式是什么?
反射的机制,无非就是先加载对应字节码中的类,然后,根据加载类的信息,一点点的去解剖其中的内容,不管你是public的还是private的,亦或是本类的还是来自原继承关系或者实现接口中的方法,我们java的反射技术 reflect,均可以将其从字节码中拉回到现实,不仅可以得到字段的名字,我们还可以获得字段的值和修改字段的值,不仅可以得到方法的申明我们还可以拿到方法的定义和唤起方。
三种方式:
一:(对象.getClass()),获取person类中的字节码文件
二:(类.class:需要输入一个明确的类,任意一个类型都有一个静态的class属性)
三:通过Class类的一个forName(String className)静态方法返回一个Class对象,className必须是全路径名称;
深拷贝和浅拷贝的区别?
浅拷贝只复制指向某个对象的指针,共享一块内存空间
深拷贝连指针和对象一起复制,完全不同的内存空间
java.lang.Object 对象中 hashCode 和 equals 方法的理解。在什么场景
下需要重新实现这两个方法?
1.equal()相等的两个对象他们的hashCode()肯定相等,也就是用equal()对比是绝对可靠的。
2.hashCode()相等的两个对象他们的equal()不一定相等,也就是hashCode()不是绝对可靠的。
所有对于需要大量并且快速的对比的话如果都用equal()去做显然效率太低,所以解决方式是,每当需要对比的时候,首先用hashCode()去对比,如果hashCode()不一样,则表示这两个对象肯定不相等(也就是不必再用equal()去再对比了),如果hashCode()相同,此时再对比他们的equal(),如果equal()也相同,则表示这两个对象是真的相同了,这样既能大大提高了效率也保证了对比的绝对正确性!(HashSet判重的做法就是这样的)
本文介绍了Java中的进程、线程和协程的区别,包括它们的资源分配、通信方式和执行效率。同时,讨论了线程与进程的并发特性、Integer的实现原理和缓存机制,以及wait、yield、sleep方法的区别。此外,还提到了String、StringBuffer和StringBuilder的使用场景,以及Java中反射的原理和应用。
1万+

被折叠的 条评论
为什么被折叠?



