参考文档:https://www.jianshu.com/p/ba7fa25d3590
对象中都包含什么?
普通对象:
1.对象头。 2.classpointer指针。 3.实例数据。 4.pading对齐。8的倍数
对象头:
Mark Word记录了对象和锁有关的信息,当这个对象被synchronized关键字当成同步锁时,围绕这个锁的一系列操作都和Mark Word有关。
Mark Word在32位JVM中的长度是32bit,在64位JVM中长度是64bit。这里我们着重说明64位的。
https://blog.csdn.net/lkforce/article/details/81128115
2.指向类的指针:该指针在32位JVM中的长度是32bit,在64位JVM中长度是64bit。Java对象的类数据保存在方法区。
3.实例数据:对象的实例数据就是在java代码中能看到的属性和他们的值。
4.对齐填充字节:因为JVM要求java的对象占的内存大小应该是8bit的倍数,所以后面有几个字节用于把对象的大小补齐至8bit的倍数,没有特别的功能。
数组对象: 1.对象头。 2.classpointer指针。 3.数组长度:4字节(该数据在32位和64位JVM中长度都是32bit。) 4.数组数据。 5.pading对齐。8的倍数
一个object对象有16个字节,原因:
1.头部 8个字节 2.class指针:被压缩了是4个字节(默认是8个字节) 。 3.Padding:4个字节。
1.接口和抽象类的区别:
相同点:1.都不可以被实例化。 2.接口的实现类或抽象类的子类都只有实现了接口的或抽象类的方法之后才能实例化。
不同点:
1.接口只有定义,不能有方法的实现。 抽象类可以有定义和实现,方法可以在抽象类中实现。
2.实现接口的关键字为implements,继承抽象类的关键字为extends。一个类可以实现多个接口,但一个类只能继承一个抽象类。所以,使用接口可以间接地实现多重继承。
3.接口强调特定功能的实现,而抽象类强调所属关系。
4.接口成员变量默认为public static final,必须赋初值,不能被修改;其所有的成员方法都是public、abstract的。抽象类中成员变量默认default,可在子类中被重新定义,也可被重新赋值;抽象方法被abstract修饰,不能被private、static、synchronized和native等修饰,必须以分号结尾,不带花括号。
5.接口被用于常用的功能,便于日后维护和添加删除,而抽象类更倾向于充当公共类的角色,不适用于日后重新对立面的代码修改。功能需要累积时用抽象类,不需要累积时用接口。
2. java中的异常有哪几类,分别怎么使用?
Throwable是所有异常的根,java.lang.Throwable
Error:错误,Java.lang.Error
Exception:异常,java.lang.Exception
Exception分为CheckedException和RuntimeException,所有RuntimeException类及其子类的实例被称为Runtime异常,不属于该范畴的异常则被称为CheckedException。
①checkedException:只有Java语言提供了Checked异常,Java认为checked异常都是可以被处理的异常,所以Java程序必须显示处理checked异常。如果程序没有处理checked异常,该程序在编译时会发生错误无法编译。这体现了Java的设计哲学:没有完善错误处理的代码根本没有机会被执行。对Checked异常处理方法有两种:
1、当前方法知道如何处理该异常,则用try...catch块来处理。
2、当前方法不知道如何处理,则在定义该方法时声明抛出该异常。
我们比较熟悉的Checked异常有
Java.lang.ClassNotFoundException
Java.lang.NoSuchMethodException
java.io.IOException
②RuntimeException
Runtime如除数是0和数组下标越界等,其产生频繁,处理麻烦,若显示申明或者捕获将会对程序的可读性和运行效率影响很大。所以由系统自动检测并将它们交给缺省的异常处理程序。当然如果你有处理要求也可以显示捕获它们。
Java.lang.ArithmeticException
Java.lang.ArrayStoreExcetpion
Java.lang.ClassCastException
Java.lang.IndexOutOfBoundsException
Java.lang.NullPointerException
6. ==和equals的区别?
1.==是判断两个变量或实例是不是指向同一个内存空间,equals是判断两个变量或实例所指向的内存空间的值是不是相同
2.==是指对内存地址进行比较 , equals()是对字符串的内容进行比较
3.==指引用是否相同, equals()指的是值是否相同
12. java中一个字符占多少个字节,扩展:int,double,long...占多少字节?
2字节(16位)。
Java基本类型占用的字节数:
1字节: byte , boolean
2字节: short , char
4字节: int , float
8字节: long , double
注:1字节(byte)=8位(bits)
13. 创建一个类的实例都有哪些办法?
java创建对象的方法常用的有5种:使用new关键字、利用java的反射机制、实现Cloneable接口使用克隆方法以及利用java序列化和反序列化实现创建对象,使用Constructor类的newInstance方法。
Constructor<Person > constructor = Person .class.getConstructor();
Person emp3 = constructor.newInstance();
//创建对象方式2:使用反射,反射方式创建对象要求被创建的对象编写空构造
Person emp2 = (Person) Class.forName("org.programming.mitra.exercises.Person").newInstance();
或者
Persone emp2 = Person.class.newInstance();
//使用clone方法创建对象:要求被创建或者被克隆的对象实现Cloneable接口,是在内存上对已有对象的克隆,所以不会调用构造函数
User u3 = (User) u1.clone();
@Override
- public Object clone() throws CloneNotSupportedException {
- // TODO Auto-generated method stub
- return super.clone();
- }
调用java.io.ObjectInputStream对象的 readObject()方法
18. 如何用java分配一段连续的1G内存空间,需要注意什么?
ByteBuffer.allocateDirect(1024*1024*1024);
21. String s = new String("abc");创建了几个String object?
1个或2个。
把上面这行代码分成String str、=、"abc"和new String()四部分来看待。String str只是定义了一个名为str的String类型的变量,因此它并没有创建对象;=是对变量str进行初始化,将某个对象的引用(或者叫句柄)赋值给它,显然也没有创建对象;
调用Class类的newInstance方法,利用反射机制创建对象。
我们正是使用new调用了String类的上面那个构造器方法创建了一个对象,并将它的引用赋值给了str变量。同时我们注意到,被调用的构造器方法接受的参数也是一个String对象,这个对象正是"abc"。
String a="abc";,这行代码被执行的时候,JAVA虚拟机首先在字符串池中查找是否已经存在了值为"abc"的这么一个对象,它的判断依据是String类equals(Object obj)方法的返回值。如果有,则不再创建新的对象,直接返回已存在对象的引用;如果没有,则先创建这个对象,然后把它加入到字符串池中,再将它的引用返回。
14. final/finally/finalize的区别?
final:java中的关键字,修饰符。
A).如果一个类被声明为final,就意味着它不能再派生出新的子类,不能作为父类被继承。因此,一个类不能同时被声明为abstract抽象类的和final的类。
B).如果将变量或者方法声明为final,可以保证它们在使用中不被改变.
1)被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。
2)被声明final的方法只能使用,不能重载。
finally:java的一种异常处理机制。
finally是对Java异常处理模型的最佳补充。finally结构使代码总会执行,而不管无异常发生。使用finally可以维护对象的内部状态,并可以清理非内存资源。特别是在关闭数据库连接这方面,如果程序员把数据库连接的close()方法放到finally中,就会大大降低程序出错的几率。
finalize:Java中的一个方法名。
Java技术使用finalize()方法在垃圾收集器将对象从内存中清除出去前,做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没被引用时对这个对象调用的。它是在Object类中定义的,因此所的类都继承了它。子类覆盖finalize()方法以整理系统资源或者执行其他清理工作。finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。
select和epoll的区别
##-select( 时间复杂度O(n) )
有I/O事件发生的时候,只能无差别轮询所有流,找出能读出数据,或者写入数据的流,对他们进行操作。所以select具有O(n)的无差别轮询复杂度,因此处理的流越多,轮询时间就越长。
select的缺点:
- 单个进程能够监视的文件描述符的数量存在最大限制,通常是1024,当然可以更改数量,但由于select采用轮询的方式扫描文件描述符,文件描述符数量越多,性能越差;(在linux内核头文件中,有这样的定义:#define __FD_SETSIZE 1024)
- 内核 / 用户空间内存拷贝问题,select需要复制大量的句柄数据结构,产生巨大的开销;
- select返回的是含有整个句柄的数组,应用程序需要遍历整个数组才能发现哪些句柄发生了事件;
- select的触发方式是水平触发,应用程序如果没有完成对一个已经就绪的文件描述符进行IO操作,那么之后每次select调用还是会将这些文件描述符通知进程。
相比select模型,poll使用链表保存文件描述符,因此没有了监视文件数量的限制,但其他三个缺点依然存在。
epoll IO多路复用模型实现机制
C10K问题由来
新到来一个TCP连接,就需要分配一个进程。假如有C10K,就需要创建1W个进程,单机负载的情况下会出现很多问题。
C10K问题的本质
C10K问题的本质上是操作系统的问题。传统的同步阻塞I/O模型处理方式都是requests per second。当创建的进程或线程多了,数据拷贝频繁(缓存I/O、内核将数据拷贝到用户进程空间、阻塞,进程/线程上下文切换消耗大, 导致操作系统崩溃,这就是C10K问题的本质。
该方式可以说是C10K问题的killer,他不去轮询监听所有文件句柄是否已经就绪。epoll只对发生变化的文件句柄感兴趣。其工作机制是,使用"事件"的就绪通知方式,通过epoll_ctl注册文件描述符fd,一旦该fd就绪,内核就会采用类似callback的回调机制来激活该fd, epoll_wait便可以收到通知, 并通知应用程序。而且epoll使用一个文件描述符管理多个描述符,将用户进程的文件描述符的事件存放到内核的一个事件表中, 这样数据只需要从内核缓存空间拷贝一次到用户进程地址空间。而且epoll是通过内核与用户空间共享内存方式来实现事件就绪消息传递的,其效率非常高。但是epoll是依赖系统的(Linux)。