part1

java中==和equals和hashCode的区别
A:java中的数据类型,可分为两类:
① ==
1.基本数据类型,也称原始数据类型

byte,short,char,int,long,float,double,boolean 他们之间的比较,应用双等号(==),比较的是他们的值。

2.引用类型(类、接口、数组)

当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址,所以,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false。

对象是放在堆中的,栈中存放的是对象的引用(地址)。由此可见’=='是对栈中的值进行比较的。如果要比较堆中对象的内容是否相同,那么就要重写equals方法了。
②equals
1、默认情况(没有覆盖equals方法)下equals方法都是调用Object类的equals方法,而Object的equals方法主要用于判断对象的内存地址引用是不是同一个地址(是不是同一个对象)。
2 、要是类中覆盖了equals方法,那么就要根据具体的代码来确定equals方法的作用了,覆盖后一般都是通过对象的内容是否相等来判断对象是否相等。例如String的equals方法即是判断值是否相等。
这里对equals重新需要注意五点:
1 自反性:对任意引用值X,x.equals(x)的返回值一定为true.
2 对称性:对于任何引用值x,y,当且仅当y.equals(x)返回值为true时,x.equals(y)的返回值一定为true;
3 传递性:如果x.equals(y)=true, y.equals(z)=true,则x.equals(z)=true
4 一致性:如果参与比较的对象没任何改变,则对象比较的结果也不应该有任何改变
5 非空性:任何非空的引用值X,x.equals(null)的返回值一定为false
③hashCode
hashCode()方法返回的就是一个数值,从方法的名称上就可以看出,其目的是生成一个hash码。hash码的主要用途就是在对对象进行散列的时候作为key输入,据此很容易推断出,我们需要每个对象的hash码尽可能不同,这样才能保证散列的存取性能。事实上,Object类提供的默认实现确实保证每个对象的hash码不同(在对象的内存地址基础上经过特定算法返回一个hash码)。Java采用了哈希表的原理。哈希(Hash)实际上是个人名,由于他提出一哈希算法的概念,所以就以他的名字命名了。 哈希算法也称为散列算法,是将数据依特定算法直接指定到一个地址上。初学者可以这样理解,hashCode方法实际上返回的就是对象存储的物理地址(实际可能并不是)。
④eqauls方法和hashCode方法关系
Java对于eqauls方法和hashCode方法是这样规定的:

(1)同一对象上多次调用hashCode()方法,总是返回相同的整型值。

(2)如果a.equals(b),则一定有a.hashCode() 一定等于 b.hashCode()。

(3)如果!a.equals(b),则a.hashCode() 不一定等于 b.hashCode()。此时如果a.hashCode() 总是不等于 b.hashCode(),会提高hashtables的性能。

(4)a.hashCode()==b.hashCode() 则 a.equals(b)可真可假

(5)a.hashCode()!= b.hashCode() 则 a.equals(b)为假。

1、equals方法用于比较对象的内容是否相等(覆盖以后)

2、hashcode方法只有在集合中用到

3、当覆盖了equals方法时,比较对象是否相等将通过覆盖后的equals方法进行比较(判断对象的内容是否相等)。

4、将对象放入到集合中时,首先判断要放入对象的hashcode值与集合中的任意一个元素的hashcode值是否相等,如果不相等直接将该对象放入集合中。如果hashcode值相等,然后再通过equals方法判断要放入对象与集合中的任意一个对象是否相等,如果equals判断不相等,直接将该元素放入到集合中,否则不放入。

int、char、long各占多少字节数
part1
int与integer的区别
int是基本数据类型,integer是int的包装数据类型,integer使用前必须初始化,它的默认值为null,int的默认值为0,integer是对象的概念,可以用new实例化。

探探对java多态的理解
1、面向对象的三大基本特征:封装、继承、多态

Java中继承的概念是:继承是指一个对象直接使用另一对象的属性和方法(此处引用百度百科)。也就是当一个子类继承了一个父类时,子类也同时继承了父类的非静态属性和方法(可以继承父类的private方法、变量、只是无法通过子类对象修改),那么意思就是子类对象可以调用父类的方法并且可以访问父类的变量(只能改变非私有变量)。

2、多态是指:父类引用指向子类对象,在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。

3、实现多态的三要素:继承 重写 父类引用指向子类对象
一般通过两种方式实现多态:覆盖(重写)、重载。
这两种方式有什么区别又有什么联系?
首先区别:
1.覆盖要求子类中的某一方法名和参数和父类中的某一方法名和参数完全一致。而重载只要求方法名一样而参数名必须不 一致
2.覆盖要求子类中的方法与父类中被覆盖的方法返回类型必须一致。而重载可以不一致(参数列表必须不一致)。
3.覆盖要求子类覆盖父类的方法中不能有新抛出的异常类型。而重载允许有新抛出的异常类型。
4.覆盖要求子类覆盖父类的方法的访问权限必须比父类的对应方法大(public > protected > default > private)。而重载 则没有这种限制。
联系:
1.都是Java中多态性的典型体现。
2.都基于Java的继承机制。

String、StringBuffer、StringBuilder区别
三者在执行速度方面的比较:StringBuilder > StringBuffer > String
(1)如果要操作少量的数据用 String;

(2)多线程操作字符串缓冲区下操作大量数据 StringBuffer;

(3)单线程操作字符串缓冲区下操作大量数据 StringBuilder。

什么是内部类?内部类的作用
内部类分类:
1普通内部类(成员内部类)
2 局部内部类(方法内或者代码块内)
局部内部类和局部变量一样,不能被public、protected、private和static修饰,只能访问方法中定义为final类型的局部变量。分为静态局部内部类(位于静态方法内或者静态代码块内)和非静态局部内部类。
3 匿名内部类
匿名内部类没有类名的内部类,不使用关键字class、extends、implements,没有构造函数,必须继承其他类或实现其他接口。匿名内部类的好处是代码更加简洁紧凑,但坏处是易读性下降。一般应用于GUI编程中实现事件处理等。
4嵌套内部类
内部类是static时,称作是嵌套类。则1)创建嵌套类的对象时不再需要其外围类的对象;2)不能从嵌套类的对象中访问非静态的外围类对象。
静态内部类不能访问外部类的普通成员变量,只能访问外部类中的静态成员和静态方法。

抽象类和接口区别
part1

抽象类的意义
1,为子类提供一个公共的类型;

2,封装子类中重复内容(成员变量和方法);

3,定义有抽象方法,子类虽然有不同的实现,但该方法的定义是一致的。

抽象类与接口的应用场景
interface的应用场合
A. 类与类之前需要特定的接口进行协调,而不在乎其如何实现。
B. 作为能够实现特定功能的标识存在,也可以是什么接口方法都没有的纯粹标识。
C. 需要将一组类视为单一的类,而调用者只通过接口来与这组类发生联系。
D. 需要实现特定的多项功能,而这些功能之间可能完全没有任何联系。

4、abstract class的应用场合
一句话,在既需要统一的接口,又需要实例变量或缺省的方法的情况下,就可以使用它。最常见的有:
A. 定义了一组接口,但又不想强迫每个实现类都必须实现所有的接口。可以用abstract class定义一组方法体,甚至可以是空方法体,然后由子类选择自己所感兴趣的方法来覆盖。
B. 某些场合下,只靠纯粹的接口不能满足类与类之间的协调,还必需类中表示状态的变量来区别不同的关系。abstract的中介作用可以很好地满足这一点。
C. 规范了一组相互协调的方法,其中一些方法是共同的,与状态无关的,可以共享的,无需子类分别实现;而另一些方法却需要各个子类根据自己特定的状态来实现特定的功能

抽象类是否可以没有方法和属性?
抽象类中可以没有抽象方法,但有抽象方法的一定是抽象类。所以,java中 抽象类里面可以没有抽象方法。注意即使是没有抽象方法和属性的抽象类,也不能被实例化。

父类的静态方法能否被子类重写
父类的静态方法可以被子类继承,但是不能重写。

进程和线程的区别
进程是资源(CPU、内存等)分配的基本单位,它是程序执行时的一个实例。程序运行时系统就会创建一个进程,并为它分配资源,然后把该进程放入进程就绪队列,进程调度器选中它的时候就会为它分配CPU时间,程序开始真正运行。

线程是程序执行时的最小单位,它是进程的一个执行流,是CPU调度和分派的基本单位,一个进程可以由很多个线程组成,线程间共享进程的所有资源,每个线程有自己的堆栈和局部变量。

线程和进程各自有什么区别和优劣呢?
进程是资源分配的最小单位,线程是程序执行的最小单位。

进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。而线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多。

线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(IPC)进行。不过如何处理好同步与互斥是编写多线程程序的难点。

但是多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间。

final,finally,finalize的区别
finalize()是在java.lang.Object里定义的,也就是说每一个对象都有这么个方法。这个方法在gc启动,该对象被回收的时候被调用。其实gc可以回收大部分的对象(凡是new出来的对象,gc都能搞定,一般情况下我们又不会用new以外的方式去创建对象),所以一般不需要实现finalize。
特殊情况下,需要实现finalize,当对象被回收的时候释放一些资源,比如:一个socket链接,在对象初始化时创建,整个生命周期内有效,那么就需要实现finalize,关闭这个链接。
使用finalize还需要注意一个事,调用super.finalize();
一个对象的finalize()方法只会被调用一次,而且finalize()被调用不意味着gc会立即回收该对象,所以有可能调用finalize()后,该对象又不需要被回收了,然后到了真正要被回收的时候,因为前面调用过一次,所以不会调用finalize(),产生问题。 所以,推荐不要使用finalize()方法,它跟析构函数不一样。
  
序列化的方式
实现Serializable / Parcelable 接口

Serializable 和Parcelable 的区别
Serializable 是java中的类,Parcelable 是安卓特有的类。
Parcelable的实现需要重写许多方法比较复杂,效率高,占用内存相对少,
Serializable 实现简单,内存开销大。

静态属性和静态方法是否可以被继承?是否可以被重写?以及原因?
可以被自雷继承但不能被子类重写
原因:
static修饰函数/变量时,其实是全局函数/变量,它与任何类都没有关系。靠这个类的好处就是这个类的成员函数调用static方法不用带类名。
注意:static关键字可以用修饰代码块.static代码块可以置于类中的任何一个位置,并可以有多个static代码块。在类初次被加载时,会按照静态代码块的顺序来执行,并且只会执行一次。

静态内部类的设计意图
静态内部类与非静态内部类之间存在一个最大的区别:非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外围内,但是静态内部类却没有。
没有这个引用就意味着:它的创建是不需要依赖于外围类的。
它不能使用任何外围类的非static成员变量和方法。
匿名内部类

1、匿名内部类是没有访问修饰符的。

2、new 匿名内部类,这个类首先是要存在的。

3、当所在方法的形参需要被匿名内部类使用,那么这个形参就必须为final。

4、匿名内部类没有明面上的构造方法,编译器会自动生成一个引用外部类的构造方法。

成员内部类、静态内部类、局部内部类和匿名内部类的理解,以及项目中的应用

谈谈对kotlin的理解

闭包和局部内部类的区别
https://www.cnblogs.com/ssp2110/p/3797666.html

string 转换成 integer的方式及原理
parseInt(String s)–内部调用parseInt(s,10)(默认为10进制)
正常判断null,进制范围,length等
判断第一个字符是否是符号位
循环遍历确定每个字符的十进制值
通过*= 和-= 进行计算拼接
判断是否为负值 返回结果。

泛型中extends和super的区别
上界通配符和下界通配符
·<? extends T>限定参数类型的上界:参数类型必须是T或T的子类型
·<? super T> 限定参数类型的下界:参数类型必须是T或T的超类型
总结为:
·<? extends T> 只能用于方法返回,告诉编译器此返参的类型的最小继承边界为T,T和T的父类都能接收,但是入参类型无法确定,只能接受null的传入
·<? super T>只能用于限定方法入参,告诉编译器入参只能是T或其子类型,而返参只能用Object类接收
?既不能用于入参也不能用于返参。

哪些情况下的对象会被垃圾回收机制处理掉?
两种判断方法。

引用计数法

这种方法是在对象的头处维护一个计数器Counter,当有一个引用指向对象的时候counter就加一,当不在引用此对象时就让counter减一。所以,当counter等于零的时候虚拟机就认为此对象时可以被回收的。看起来好像有点道理,但是这种方法存在一个致命的问题:

可达性分析算法

Java就是使用此方法作为判断对象是否可被回收的。虚拟机会先将一些对象定义为GC Roots,从GC Roots出发一直沿着引用链向下寻找,如果某个对象不能通过GC Roots寻找到,那么虚拟机就认为该对象可以被回收。我们举个例子,如下图:
part1
当对象D不在引用对象A时,尽管A、B、C互相还持有引用,GC依然会回收ABC所占用的内存。那么还有个疑问,什么样的对象可以被看做是GC Roots呢?
虚拟机栈(栈桢中的本地变量表)中的引用的对象
方法区中的类静态属性引用的对象
方法区中的常量引用的对象
本地方法栈中JNI(Native方法)的引用的对象

讲一下常见编码方式?
ASCII码:共有128个,用一个字节的低7位表示

ISO8859-1:在ASCII码的基础上涵盖了大多数西欧语言字符,仍然是单字节编码,它总共能表示256个字符

GB2312:全称为《信息交换用汉字编码字符集基本集》,它是双字节编码,总的编码范围是A1~F7
A1~A9 ·符号区
B0~F7 汉字区

GBK:数字交换用汉字编码字符集》,它可能是单字节、双字节或者四字节编码,与GB2312编码兼容

UTF-16:具体定义了Unicode字符在计算机中的存取方法。采用2字节来表示Unicode转化格式,它是定长的表示方法,不论什么字符都可以用两个字节表示

UTF-8: UTF-8采用一种变长技术,每个编码区域有不同的字码长度,不同的字符可以由1~6个字节组成。
如果一个字节,最高位为0,表示这是一个ASCII字符(00~7F)
如果一个字节,以11开头,连续的1的个数暗示这个字符的字节数

utf-8编码中的中文占几个字节;int型几个字节?
utf-8的编码规则:
如果一个字节,最高位为0,表示这是一个ASCII字符(00~7F)
如果一个字节,以11开头,连续的1的个数暗示这个字符的字节数
一个utf8数字占1个字节
一个utf8英文字母占1个字节
少数是汉字每个占用3个字节,多数占用4个字节。

静态代理和动态代理的区别,什么场景使用?

所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。
优点:使用者只关心业务逻辑,不需要着眼内部实现,方便后期的变更和部分共用代码的统一处理
缺点:当代理类中出现的被代理类越来越多时,内部就会显得非常臃肿。反而不利于管理阅读。
应用:一些第三方框架的代理,便后后期替换或者定制化变更。
动态代理类的源码是在程序运行期间由JVM根据反射等机制动态的生成,所以不存在代理类的字节码文件。代理类和委托类的关系是在程序运行时确定。
优点:拥有静态代理的优点,同时省去了很多代码,并且扩展性更强,通过反射可以执行任意类型的被代理类方法
缺点:只能代理实现了接口的类,而没有实现接口的类就不能实现动态代理。�通过反射在性能上可以会有一定程度上的性能损耗。
应用:被代理类庞大时,需要在某些方法执行前后处理一些事情时,亦或接口类与实现类经常变动时(因为使用反射所以方法的增删改并不需要修改invoke方法)。
https://blog.csdn.net/ikownyou/article/details/53081426
https://www.jianshu.com/p/ba54b0f23c16

Java的异常体系
Throwable (Exception,Error)

谈谈你对解析与分派的认识

修改对象A的equals方法的签名,那么使用HashMap存放这个对象实例的时候,会调用哪个equals方法?

Java中实现多态的机制是什么?

如何将一个Java对象序列化到文件里?

说说你对Java反射的理解

说说你对Java注解的理解
https://mp.weixin.qq.com/s/NwlIy_knmx4Es7kFnk0gRQ?

说说你对依赖注入的理解

说一下泛型原理,并举例说明
泛型可以消除代码中的强制类型转换,同时获得一个附加的类型检查层,该检查层可以防止有人将错误类型的键或值保存在集合中。这就是泛型所做的工作。

Java中String的了解

String为什么要设计成不可变的?

Object类的equal和hashCode方法重写,为什么?