1.哪些情况下的对象会被垃圾回收机制处理掉?
答:首先先回答定义:内存回收就是释放掉在内存中已经没用的对象
如何判断对象没用的方法有四种:
1>标记回收法
先遍历对象图,然后将可以回收的对象进行记录,一般使用单线程工作,有可能会产生内存碎片,因为执行上述操作会将内存分为一块一块的碎片
2>标记压缩回收法
在第一种回收方法的情况下再多加一步,将所有的存活的对象压缩到内存的一段,这样就把内存的碎片整理合为一大块,然后再利用内存区域,提高内存的利用率
3>复制回收法
首先将内存西安分为两块部分,当gc运行的时候把可到达对象复制到另一半控件,再清空正在使用的控件的全部对象,这种方法适用于短生存期的对象,持续复制长生存期的对象会导致效率降低
4>分发回收法
把内存空间分为两个或者多个区域,如年轻代和老年代,年轻代的特点是对象会很快被回收,因此才年轻代适用效率比较高的算法,当一个对象经过几次回收后依然存活,对象就会被放入称为老年的内存空间,老年代则采取标记压缩算法
还有在垃圾回收的时候当检测到对象没有用了,需要被回收的时候并不会马上被回收,而是将其放入到一个准备回收的队列,去执行finalize方法。。然等到下次内存回收的时候要是他还是没有被任何人引用的话,就将其给回收了。(如果在finalize方法中重新给对象加个引用,这样对象是有可能不会被回收的)不过finalize方法不推荐使用,他跟C++中的析构函数不同,我们既不能确定什么时候他回被回收,也不能保证这个方法一定会被执行。
2.讲一下常见编码方式?
答:
编码的原因可以总结为:
计算机中存储信息的最小单元是一个字节即 8 个 bit,所以能表示的字符范围是 0~255 个
人类要表示的符号太多,无法用一个字节来完全表示
要解决这个矛盾必须需要一个新的数据结构 char,从 char 到 byte 必须编码
ASCII 码
学过计算机的人都知道 ASCII 码,总共有 128 个,用一个字节的低 7 位表示,0~31 是控制字符如换行回车删除等;32~126 是打印字符,可以通过键盘输入并且能够显示出来。
ISO-8859-1
128 个字符显然是不够用的,于是 ISO 组织在 ASCII 码基础上又制定了一些列标准用来扩展 ASCII 编码,它们是 ISO-8859-1~ISO-8859-15,其中 ISO-8859-1 涵盖了大多数西欧语言字符,所有应用的最广泛。ISO-8859-1 仍然是单字节编码,它总共能表示 256 个字符。
GB2312
它的全称是《信息交换用汉字编码字符集 基本集》,它是双字节编码,总的编码范围是 A1-F7,其中从 A1-A9 是符号区,总共包含 682 个符号,从 B0-F7 是汉字区,包含 6763 个汉字。
GBK
全称叫《汉字内码扩展规范》,是国家技术监督局为 windows95 所制定的新的汉字内码规范,它的出现是为了扩展 GB2312,加入更多的汉字,它的编码范围是 8140~FEFE(去掉 XX7F)总共有 23940 个码位,它能表示 21003 个汉字,它的编码是和 GB2312 兼容的,也就是说用 GB2312 编码的汉字可以用 GBK 来解码,并且不会有乱码。
GB18030
全称是《信息交换用汉字编码字符集》,是我国的强制标准,它可能是单字节、双字节或者四字节编码,它的编码与 GB2312 编码兼容,这个虽然是国家标准,但是实际应用系统中使用的并不广泛。
UTF-16
说到 UTF 必须要提到 Unicode(Universal Code 统一码),ISO 试图想创建一个全新的超语言字典,世界上所有的语言都可以通过这本字典来相互翻译。可想而知这个字典是多么的复杂,关于 Unicode 的详细规范可以参考相应文档。Unicode 是 Java 和 XML 的基础,下面详细介绍 Unicode 在计算机中的存储形式。
UTF-16 具体定义了 Unicode 字符在计算机中存取方法。UTF-16 用两个字节来表示 Unicode 转化格式,这个是定长的表示方法,不论什么字符都可以用两个字节表示,两个字节是 16 个 bit,所以叫 UTF-16。UTF-16 表示字符非常方便,每两个字节表示一个字符,这个在字符串操作时就大大简化了操作,这也是 Java 以 UTF-16 作为内存的字符存储格式的一个很重要的原因。
UTF-8
UTF-16 统一采用两个字节表示一个字符,虽然在表示上非常简单方便,但是也有其缺点,有很大一部分字符用一个字节就可以表示的现在要两个字节表示,存储空间放大了一倍,在现在的网络带宽还非常有限的今天,这样会增大网络传输的流量,而且也没必要。而 UTF-8 采用了一种变长技术,每个编码区域有不同的字码长度。不同类型的字符可以是由 1~6 个字节组成。
UTF-8 有以下编码规则:
如果一个字节,最高位(第 8 位)为 0,表示这是一个 ASCII 字符(00 - 7F)。可见,所有 ASCII 编码已经是 UTF-8 了。
如果一个字节,以 11 开头,连续的 1 的个数暗示这个字符的字节数,例如:110xxxxx 代表它是双字节 UTF-8 字符的首字节。
如果一个字节,以 10 开始,表示它不是首字节,需要向前查找才能得到当前字符的首字节
转载自http://www.whohelpme.com/blog/main/NO1.html
3.utf-8编码中的中文占几个字节;int型几个字节?
答:UTF-8占用三个字节,在java中,int类型占四个字节
4.静态代理和动态代理的区别,什么场景使用?
答:
代理模式是常用的Java设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。按照代理类的创建时期,代理类可分为两种。
静态代理类:由程序员创建或由特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。
动态代理类:在程序运行时,运用反射机制动态创建而成。
静态代理通常只代理一个类,动态代理是代理一个接口下的多个实现类。
静态代理事先知道要代理的是什么,而动态代理不知道要代理什么东西,只有在运行时才知道。
动态代理是实现JDK里的InvocationHandler接口的invoke方法,但注意的是代理的是接口,也就是你的业务类必须要实现接口,通过Proxy里的newProxyInstance得到代理对象。
还有一种动态代理CGLIB,代理的是类,不需要业务类继承接口,通过派生的子类来实现代理。通过在运行时,动态修改字节码达到修改类的目的。
推荐查看博客 https://blog.csdn.net/mine_song/article/details/71373305?locationNum=15&fps=1
5.Java的异常体系
答:Thorwable类所有异常和错误的超类,有两个子类Error和Exception,分别表示错误和异常,其中异常类Exception又分为运行时异常(RuntimeException)和非运行时异常, 这两种异常有很大的区别,也称之为不检查异常(Unchecked Exception) 和检查异常(Checked Exception)。下面将详细讲述这些异常之间的区别与联系:
1、Error与Exception
Error是程序无法处理的错误,比如OutOfMemoryError、ThreadDeath等。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止。 Exception是程序本身可以处理的异常,这种异常分两大类运行时异常和非运行时异常。 程序中应当尽可能去处理这些异常。
2、运行时异常和非运行时异常
运行时异常都是RuntimeException类及其子类异常,如NullPointerException、IndexOutOfBoundsException等, 这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的, 程序应该从逻辑角度尽可能避免这类异常的发生。 非运行时异常是RuntimeException以外的异常,类型上都属于Exception类及其子类。 从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过, 如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常
6.谈谈你对解析与分派的认识。
由于比较深入,建议从虚拟机入手《深入理解Java虚拟机》读书笔记 - 简书
7.说说你对Java反射的理解
答:最简单的理解,反射就是把Java类中的各种成分映射成相应的Java类。
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
Java的反射非常强大,传递class, 可以动态的生成该类、取得这个类的所有信息,包括里面的属性、方法以及构造函数等,甚至可以取得其父类或父接口里面的内容。
8.说说你对Java注解的理解
答:我对java的理解(一)——注解就是贴标签 - nobounds - 博客园
9.说说你对依赖注入的理解
答:依赖注入最大的作用是用来解耦
依赖注入是指当一个对象要与其他对象发生依赖关系时,通过抽象来注入所依赖的对象。A对象依赖于B对象,等价于A对象内部存在对B对象的“调用”,而前提是A对象内部拿到了B对象的引用
10.说一下泛型原理,并举例说明
答:泛型是jdk1.5引入的,使编程人员能使用类型抽象,通常用于集合。
泛型只在编译阶段有效,在编译过程中,会在对象进入和离开的地方,添加类型检查和类型转换方法,成功编译后的class文件不包含泛型信息。
泛型在使用前必须声明,泛型类和泛型方法声明方式不同:
public class Test {//T就是声明,声明后可以直接定义T类型的 anyObject
T anyObject;
//这里就是声明了两个泛型
public K getK(V objectV) {
K kInstance = obtainKFromAnyWay(objectV);
retuan kInstance ;
}
}
在理解时,可以把泛型代入任意实际类型,声明即可使用,使用时需要注意类型匹配和转换。
通过通配符?可以限定泛型的父类
11.Java中String的了解,String为什么要设计成不可变的?
答:建议阅读这篇博客,写的相当详细深入理解Java中的String - 平凡希 - 博客园
本人是一名android开发人员,在以往的面试的过程中很少遇到这种面试题,在写这篇文章的时候也学习了很多内容,写的不好请大家多多指点