Java程序猿想超神,我来回答这些问题(java基础补充篇)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_32635069/article/details/80872040

1、epoll和select
这是两种处理IO并发的两种机制,在linux没有实现epoll实践驱动机制之前,我们一般选择使用select或者poll等IO多路复用的方法来实现并发服务程序,但是现在,大数据,高并发的时代里,主流已经变成了epoll
举一个简单的栗子解释他们两个的区别:
你和你女朋友在餐馆吃饭,你们点了一大桌菜,你女朋友饿坏了,总是催你去问问有没有做好的菜了,于是你就一会一去问,没有做好的菜就回到位置上,一会儿再去问(这就是select的工作机制),于是你成功的把前台问的不耐烦了,他说你不要再过来问了,我知道你点的什么菜,等你的才好了,我叫你过来(这就是epoll的机制)
具体原理大家可以看看 select和epoll的原理概述
2、JVM内存和垃圾回收
JVM的内存结构
这里写图片描述
方法区:包含类加载的信息(类名,修饰符等),final修饰的常量,静态变量,构造函数,类中的字段和方法的信息,一般不会GC,如果加载的类过多,会报PermGen Space异常,方法区是全局共享运行常量池常量的空间分配一般在编译期就可以确定,而运行常量池中包含的是在运行时使用的常量,如String的字符串常量池

疑问,运行常量池中只在字符串中由使用吗?
显然不可能,例如:Byte,Short,Integer,Long,Character,Boolean。这5种包装类默认创建了数值[-128,127]的相应类型的缓存数据
样例:

Integer a = 100;
Integer b = 100;
if (a == b){
    return true;
}else{
    return false;
}

结果会为 true,但是如果你将100换作 [ -128, 127 ] 区间之外的,那么这样判断就是false了,因为两个对象使用 == 比较的时地址,如果真的要比较值的话,a.equals(b)方法

用于存放实例化的对象和数组,就是使用new关键字创建的对象,全局共享,所有线程共享,GC最频繁的地方

虚拟机栈
虚拟机栈使用操作系统内存,生命周期是对应线程相同,线程私有,每个方法对应一个栈帧,当方法执行时入栈,执行完毕出栈,栈帧存储着局部变量表、动态链接、操作数和方法出口等信息
局部变量表:每个变量对应值,以及对象的地址,在编译器其内存空间就会被确认,运行期不会变

本地方法栈
线程私有用于支持native方法的执行,存储每个native方法的运行状态

native方法
被native关键字修饰的方法叫做本地方法,本地方法和其它方法不一样,本地方法意味着和平台有关,因此使用了native的程序可移植性都不太高。另外native方法在JVM中运行时数据区也和其它方法不一样,它有专门的本地方法栈。native方法主要用于加载文件和动态链接库,由于Java语言无法访问操作系统底层信息(比如:底层硬件设备等),这时候就需要借助C语言来完成了。被native修饰的方法可以被C语言重写,所以native关键字一般在需要使用其他语言时使用

程序计数器
线程私有,是一个很小的内存区域,直接被划分在CPU上,用于存储当前执行字节码的行号

垃圾回收
上面所描述的五个区,虚拟机栈,本地方法栈,程序计数器是不需要GC机制的,因为它们是线程私有的,只有方法区和堆区需要垃圾回收,回收的对象是那些,不存在任何引用的对象

GC的算法

这个帐暂且记下,有些多,回头补上

3、hashMap实现线程安全
有三种办法:
- 替换成hashtable,整个表上锁
- 使用Collection类的synchronizedMap方法包装一下
- 使用ConcurrentHashMap方法,使用分段锁来保证线程安全

这里写图片描述

4、浅拷贝和深度拷贝

浅拷贝和深拷贝的概念都是针对对象而言
浅拷贝是拷贝栈区的引用
深拷贝则是拷贝堆区中的对象

以下所指的浅拷贝与深拷贝都是针对于Code对象

Code code = new Code();
Code pCode = code;//浅拷贝
code mCode = code.clone();//深拷贝

5、类加载器的实践
类加载器的类型在之前已经讲过了,这里就略过了,类加载器用法,还可以用作反射机制
name可以放在配置文件中传入,这样使得整个代码更为灵活

String name = "com.impl.neu.test";
Test test = (Test)class.forName(name).newInstance();

6、原型模式,类实现克隆接口
通过改写clone()方法实现深拷贝,为什么要有克隆的方法,因为每次通过new来新建一个对象,如果构造函数的执行时间很长,那么多次执行的话,初始化操作太低效了

猜你喜欢

转载自blog.csdn.net/qq_32635069/article/details/80872040