答案只写了Java基础的部分,有空会接着写。答案并不是标准答案,有错的地方还请指正
面试题目来中鸿洋大神的微信公众号分享:BAT大厂面试题
(一)java面试题
(1)java基础面试知识点
java中==和equals和hashCode的区别
- ==在比较基本数据类型时比较的是值,而用==号比较两个对象时比较的是两个对象的地址值
- 那equals()方法呢?我们可以通过查看源码知道,equals()方法存在于Object类中,因为Object类是所有类的直接或间接父类,也就是说所有的类中的equals()方法都继承自Object类,而通过源码我们发现,Object类中equals()方法底层依赖的是==号,那么,在所有没有重写equals()方法的类中,调用equals()方法其实和使用==号的效果一样,也是比较的地址值,然而,Java提供的所有类中,绝大多数类都重写了equals()方法,重写后的equals()方法一般都是比较两个对象的值。
- hashCode()方法是从Object类中继承过来的,它也用来鉴定两个对象是否相等。Object类中的hashCode()方法返回对象是在内存中地址转换成的一个int值,所以如果没有重写hashCode()方法,任何对象的hashCode()方法都是不相等的。
- equals()方法返回值相等,hashCode()方法返回值一定相等。
- hashCode()方法返回值不相等,equals()方法返回值一定不相等。
- hashCode()方法返回值相等,equals()方法返回值可能相等,也可能不相等。
int、char、long各占多少字节数
数据类型 字节(byte) 位(bit) 表数范围 byte 1 8 -2^7 ~ 2^7 - 1 short 2 16 -2^15 ~ 2^15 - 1 char 2 16 -2^15 ~ 2^15 - 1 int 4 32 -2^31 ~ 2^31 - 1 float 4 32 -2^31 ~ 2^31 - 1 doudle 8 64 -2^63 ~ 2^63 - 1 long 8 64 -2^63 ~ 2^63 - 1 int与integer的区别
- 1、Integer是int提供的封装类,而int是Java的基本数据类型;
- 2、Integer默认值是null,而int默认值是0;
- 3、声明为Integer的变量需要实例化,而声明为int的变量不需要实例化;
- 4、Integer是对象,用一个引用指向这个对象,而int是基本类型,直接存储数值。
谈谈对java多态的理解
多态的存在有三个前提:
- 1.要有继承关系
- 2.子类要重写父类的方法
- 3.父类引用指向子类对(Parent p = new Child())
String、StringBuffer、StringBuilder区别
- 1.String是不可变类,String对象一旦创建,其值就不能被改变,重新赋值其实是两个对象。
- 2.StringBuffer是可变类,对象被创建后仍然可以对其值进行修改。
- 3.实例化String时,可以利用构造函数(String s = new String(“sss”))的方式来初始化或者用赋值(String = “sss”)的方式初始化。 StringBuffer只能通过构造函数(StringBuffer s = new StringBuffer(“bbb”))的方式初始化。
什么是内部类?内部类的作用
扫描二维码关注公众号,回复: 10524308 查看本文章1.内部类( Inner Class )就是定义在另外一个类里面的类。与之对应,包含内部类的类被称为外部类。
2.作用:- 内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类
- 内部类的方法可以直接访问外部类的所有数据,包括私有的数据
- 内部类所实现的功能使用外部类同样可以实现,只是有时使用内部类更方便
3.内部类有几种呢?
- 1.成员内部类
- 2.静态内部类
- 3.方法内部类(局部内部类)
- 4.匿名内部类
抽象类和接口区别
设计思想不同,使用动机不同。
- 抽象类和接口设计的时候,设计思想不同
- 设计抽象类是自下而上的过程,因为调用者子类需要某些属性和特有行为,所以调用者继承抽象类
- 设计接口是自上而下的过程,接口规范某一行为,我某类需要这个行为,调用者实现某接口
开发者使用的时候,使用动机不同.
- 开发者继承抽象类是为了使用抽象类的属性和行为;
- 开发者实现接口只是为了使用接口的行为.
来源:来源知乎用户
1、抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。
- 2、抽象类要被子类继承,接口要被类实现。
- 3、接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现
- 4、接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
- 5、抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。
- 6、抽象方法只能申明,不能实现,接口是设计的结果 ,抽象类是重构的结果
- 7、抽象类里可以没有抽象方法
- 8、如果一个类里有抽象方法,那么这个类只能是抽象类
- 9、抽象方法要被实现,所以不能是静态的,也不能是私有的。
- 10、接口可继承接口,并可多继承接口,但类只能单根继承。
- 抽象类和接口设计的时候,设计思想不同
抽象类的意义
- 1.抽象类更利于代码的维护和重用。
- 2.抽象类和抽象方法用 abstract 关键字修饰。
- 3.抽象类不能被实例化。
- 4.抽象类除了不能直接实例化外,其它特性都和普通类一样,同样有成员变量,常量,成员方法。而抽象方法是强制子类实现的功能。
抽象类与接口的应用场景
- interface的应用场合
A. 类与类之前需要特定的接口进行协调,而不在乎其如何实现。
B. 作为能够实现特定功能的标识存在,也可以是什么接口方法都没有的纯粹标识。
C. 需要将一组类视为单一的类,而调用者只通过接口来与这组类发生联系。
D. 需要实现特定的多项功能,而这些功能之间可能完全没有任何联系。 - abstract class的应用场合
一句话,在既需要统一的接口,又需要实例变量或缺省的方法的情况下,就可以使用它。最常见的有:
A. 定义了一组接口,但又不想强迫每个实现类都必须实现所有的接口。可以用abstract class定义一组方法体,甚至可以是空方法体,然后由子类选择自己所感兴趣的方法来覆盖。
B. 某些场合下,只靠纯粹的接口不能满足类与类之间的协调,还必需类中表示状态的变量来区别不同的关系。abstract的中介作用可以很好地满足这一点。
C. 规范了一组相互协调的方法,其中一些方法是共同的,与状态无关的,可以共享的,无需子类分别实现;而另一些方法却需要各个子类根据自己特定的状态来实现特定的功能
- interface的应用场合
抽象类是否可以没有方法和属性?
- 抽象类里面不一定有抽象方法 ,但是有抽象方法一定是抽象类,属性和普通类属性一样
接口的意义
- 重要性:在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制。正是由于这两种机制的存在,才赋予了Java强大的 面向对象能力。
- 简单、规范性:如果一个项目比较庞大,那么就需要一个能理清所有业务的架构师来定义一些主要的接口,这些接口不仅告诉开发人员你需要实现那些业务,而且也将命名规范限制住了(防止一些开发人员随便命名导致别的程序员无法看明白)。
- 维护、拓展性:比如你要做一个画板程序,其中里面有一个面板类,主要负责绘画功能,然后你就这样定义了这个类。
可是在不久将来,你突然发现这个类满足不了你了,然后你又要重新设计这个类,更糟糕是你可能要放弃这个类,那么其他地方可能有引用他,这样修改起来很麻烦。
如果你一开始定义一个接口,把绘制功能放在接口里,然后定义类时实现这个接口,然后你只要用这个接口去引用实现它的类就行了,以后要换的话只不过是引用另一个类而已,这样就达到维护、拓展的方便性。 - 安全、严密性:接口是实现软件松耦合的重要手段,它描叙了系统对外的所有服务,而不涉及任何具体的实现细节。这样就比较安全、严密一些(一般软件服务商考虑的比较多)。
泛型中extends和super的区别
extends
和super
是Java泛型中的“通配符(Wildcards)”<? extends T>
限定参数类型的上界:参数类型必须是T或T的子类型<? super T>
限定参数类型的下界:参数类型必须是T或T的超类型总结为:
<? extends T>
不能往里存,只能往外取。<? super T>
不影响往里存,但往外取只能放在Object对象里
PECS原则:
- 频繁往外读取内容的,适合用上界extends 。
- 经常往里插入的,适合用下界super 。
父类的静态方法能否被子类重写
- 父类的静态方法可以被子类继承,但是不能重写。
进程和线程的区别
- 进程是cpu资源分配的最小单位,而线程是CPU调度的基本单元
- 同一个进程中可以包括多个线程,并且线程共享整个进程的资源(寄存器、堆栈、上下文),一个进行至少包括一个线程。
final,finally,finalize的区别
- final修饰符,用于修饰类、成员变量和成员方法
- finally用在异常处理中定义总是执行代码,无论try块中的代码是否引发异常,catch是否匹配成功,finally块中的代码总是被执行,除非JVM被关闭(System.exit(1)),通常用作释放外部资源(不会被垃圾回收器回收的资源)。
- finalize()方法是Object类中定义的方法,当垃圾回收器将无用对象从内存中清除时,该对象的finalize()方法被调用。由于该方法是protected方法,子类可以通过重写(override)该方法以整理资源或者执行其他的清理工作。
序列化的方式
- 实现Serializable接口(是JavaSE本身就支持的)
- 实现Parcelable接口(是Android特有功能,效率比实现Serializable接口高效,可用于Intent数据传递,也可以用于进程间通信(IPC))
Serializable 和Parcelable 的区别
- 编码上:
- Serializable代码量少,写起来方便, Parcelable代码多一些
效率上:
- Parcelable的速度比高十倍以上
1)在使用内存的时候,Parcelable比Serializable性能高,所以推荐使用Parcelable。
- 2)Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。
- 3)Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。尽管Serializable效率低点,但此时还是建议使用Serializable 。
- 编码上:
静态属性和静态方法是否可以被继承?是否可以被重写?以及原因?
- java中静态属性和静态方法可以被继承,但是没有被重写(overwrite)而是被隐藏.
- 原因:
- 1)、静态方法和属性是属于类的,调用的时候直接通过类名.方法名完成对,不需要继承机制及可以调用。如果子类里面定义了静态方法和属性,那么这时候父类的静态方法或属性称之为”隐藏”。如果你想要调用父类的静态方法和属性,直接通过父类名.方法或变量名完成,至于是否继承一说,子类是有继承静态方法和属性,但是跟实例方法和属性不太一样,存在”隐藏”的这种情况。
- 2)、多态之所以能够实现依赖于继承、接口和重写、重载(继承和重写最为关键)。有了继承和重写就可以实现父类的引用指向不同子类的对象。重写的功能是:”重写”后子类的优先级要高于父类的优先级,但是“隐藏”是没有这个优先级之分的。
- 3)、静态属性、静态方法和非静态的属性都可以被继承和隐藏而不能被重写,因此不能实现多态,不能实现父类的引用可以指向不同子类的对象。非静态方法可以被继承和重写,因此可以实现多态。
静态内部类的设计意图
- 只是为了降低包的深度,方便类的使用,静态内部类适用于包含类当中,但又不依赖与外在的类,不用使用外在类的非静态属性和方法,只是为了方便管理类结构而定义。在创建静态内部类的时候,不需要外部类对象的引用。
成员内部类、静态内部类、局部内部类和匿名内部类的理解,以及项目中的应用
- 内部类可以用private, protected, public或者package private(什么都不写, 称之为package private, 也就是包权限)修饰
- 成员内部类
class OuterClass {
...
class InnerClass {
...
}
} - 静态内部类
class OuterClass {
...
static class InnerClass {
...
}
} - 局部内部类
class OuterClass {
...
private void doSth(){
...
class InnerClass {
//注意,局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的。
...
}
}
} - 匿名内部类
class OuterClass {
...
InnerClass ic = new InnerClass() {
public void doSth() {
...
};
}
谈谈对kotlin的理解
- 代码的大幅度精简
- 100% 兼容 Java 代码
- 函数式编程
- 各种语法糖
闭包和局部内部类的区别
- Java中并不能显式的支持闭包,但在JAVA中,闭包是通过“接口+内部类”实现
- 例如:一个接口程序员和一个基类作家都有一个相同的方法work,相同的方法名,但是其含义完全不同,这时候就需要闭包。
class Writer {//作家基类
void work(){};
}
interface programmer{//程序员接口
void work();
} - 闭包实现代码如下:
public class WriterProgrammer extends Writer {
@Override
public void work(){
//写作
}
public void code(){
//写代码
}
class ProgrammerInner implements programmer{
@Override
public void work(){
code();
}
}
} - 实际项目中没怎么用过闭包,因此不能对他的好坏进行评论。
string 转换成 integer的方式及原理
- Integer.valueOf(str);
(2) java深入源码级的面试题(有难度)
- 哪些情况下的对象会被垃圾回收机制处理掉?
- 讲一下常见编码方式?
- utf-8编码中的中文占几个字节;int型几个字节?
- 静态代理和动态代理的区别,什么场景使用?
- Java的异常体系
- 谈谈你对解析与分派的认识。
- 修改对象A的equals方法的签名,那么使用HashMap存放这个对象实例的时候,会调用哪个equals方法?
- Java中实现多态的机制是什么?
- 如何将一个Java对象序列化到文件里?
- 说说你对Java反射的理解
- 说说你对Java注解的理解
- 说说你对依赖注入的理解
- 说一下泛型原理,并举例说明
- Java中String的了解
- String为什么要设计成不可变的?
- Object类的equal和hashCode方法重写,为什么?
(3)数据结构
- 常用数据结构简介
- 并发集合了解哪些?
- 列举java的集合以及集合之间的继承关系
- 集合类以及集合框架
- 容器类介绍以及之间的区别(容器类估计很多人没听这个词,Java容器主要可以划分为4个部分: - List列表、Set集合、Map映射、工具类(Iterator迭代器、Enumeration枚举类、Arrays和Collections),具体的可以看看这篇博文 Java容器类 http://alexyyek.github.io/2015/04/06/Collection/)
- List,Set,Map的区别
- List和Map的实现方式以及存储方式
- HashMap的实现原理
- HashMap数据结构?
- HashMap源码理解
- HashMap如何put数据(从HashMap源码角度讲解)?
- HashMap怎么手写实现?
- ConcurrentHashMap的实现原理
- ArrayMap和HashMap的对比
- HashTable实现原理
- TreeMap具体实现
- HashMap和HashTable的区别
- HashMap与HashSet的区别
- HashSet与HashMap怎么判断集合元素重复?
- 集合Set实现Hash怎么防止碰撞
- ArrayList和LinkedList的区别,以及应用场景
- 数组和链表的区别
- 二叉树的深度优先遍历和广度优先遍历的具体实现
- 堆的结构
- 堆和树的区别
- 堆和栈在内存中的区别是什么(解答提示:可以从数据结构方面以及实际实现方面两个方面去回答)?
- 什么是深拷贝和浅拷贝
- 手写链表逆序代码
- 讲一下对树,B+树的理解
- 讲一下对图的理解
- 判断单链表成环与否?
- 链表翻转(即:翻转一个单项链表)
- 合并多个单有序链表(假设都是递增的)
(4)线程、多线程和线程池
- 开启线程的三种方式?
- 线程和进程的区别?
- 为什么要有线程,而不是仅仅用进程?
- run()和start()方法区别
- 如何控制某个方法允许并发访问线程的个数?
- 在Java中wait和seelp方法的不同;
- 谈谈wait/notify关键字的理解
- 什么导致线程阻塞?
- 线程如何关闭?
- 讲一下java中的同步的方法
- 数据一致性如何保证?
- 如何保证线程安全?
- 如何实现线程同步?
- 两个进程同时要求写或者读,能不能实现?如何防止进程的同步?
- 线程间操作List
- Java中对象的生命周期
- Synchronized用法
- synchronize的原理
- 谈谈对Synchronized关键字,类锁,方法锁,重入锁的理解
- static synchronized 方法的多线程访问和作用
- 同一个类里面两个synchronized方法,两个线程同时访问的问题
- volatile的原理
- 谈谈volatile关键字的用法
- 谈谈volatile关键字的作用
- 谈谈NIO的理解
- synchronized 和volatile 关键字的区别
- synchronized与Lock的区别
- ReentrantLock 、synchronized和volatile比较
- ReentrantLock的内部实现
- lock原理
- 死锁的四个必要条件?
- 怎么避免死锁?
- 对象锁和类锁是否会互相影响?
- 什么是线程池,如何使用?
- Java的并发、多线程、线程模型
- 谈谈对多线程的理解
- 多线程有什么要注意的问题?
- 谈谈你对并发编程的理解并举例说明
- 谈谈你对多线程同步机制的理解?
- 如何保证多线程读写文件的安全?
- 多线程断点续传原理
- 断点续传的实现
(5)并发编程有关知识点
(这个是一般Android开发用的少的,所以建议多去看看):
平时Android开发中对并发编程可以做得比较少,Thread这个类经常会用到,但是我们想提升自己的话,一定不能停留在表面,,我们也应该去了解一下java的关于线程相关的源码级别的东西。
学习的参考资料如下:
Java 内存模型
- java线程安全总结
http://www.iteye.com/topic/806990 - 深入理解java内存模型系列文章
http://ifeve.com/java-memory-model-0/
线程状态:
- 一张图让你看懂JAVA线程间的状态转换
https://my.oschina.net/mingdongcheng/blog/139263
锁:
- 锁机制:synchronized、Lock、Condition
http://blog.csdn.net/vking_wang/article/details/9952063 - Java 中的锁
http://wiki.jikexueyuan.com/project/java-concurrent/locks-in-java.html
并发编程:
- Java并发编程:Thread类的使用
http://www.cnblogs.com/dolphin0520/p/3920357.html - Java多线程编程总结
http://blog.51cto.com/lavasoft/27069 - Java并发编程的总结与思考
https://www.jianshu.com/p/053943a425c3# - Java并发编程实战—–synchronized
http://www.cnblogs.com/chenssy/p/4701027.html - 深入分析ConcurrentHashMap
http://www.infoq.com/cn/articles/ConcurrentHashMap#
(二)Android面试题
(1)Android基础知识点
四大组件是什么
- Activity
- Service
- Broadcast Receiver
- Content Provider
四大组件的生命周期和简单用法
- Activity之间的通信方式
- Activity各种情况下的生命周期
- 横竖屏切换的时候,Activity 各种情况下的生命周期
- Activity与Fragment之间生命周期比较
- Activity上有Dialog的时候按Home键时的生命周期
- 两个Activity 之间跳转时必然会执行的是哪几个方法?
- 前台切换到后台,然后再回到前台,Activity生命周期回调方法。弹出Dialog,生命值周期回调方法。
- Activity的四种启动模式对比
- Activity状态保存于恢复
- fragment各种情况下的生命周期
- Fragment状态保存startActivityForResult是哪个类的方法,在什么情况下使用?
- 如何实现Fragment的滑动?
- fragment之间传递数据的方式?
- Activity 怎么和Service 绑定?
- 怎么在Activity 中启动自己对应的Service?
- service和activity怎么进行数据交互?
- Service的开启方式
- 请描述一下Service 的生命周期
- 谈谈你对ContentProvider的理解
- 说说ContentProvider、ContentResolver、ContentObserver 之间的关系
- 请描述一下广播BroadcastReceiver的理解
- 广播的分类
- 广播使用的方式和场景
- 在manifest 和代码中如何注册和使用BroadcastReceiver?
- 本地广播和全局广播有什么差别?
- BroadcastReceiver,LocalBroadcastReceiver 区别
- AlertDialog,popupWindow,Activity区别
- Application 和 Activity 的 Context 对象的区别
- Android属性动画特性
- 如何导入外部数据库?
- LinearLayout、RelativeLayout、FrameLayout的特性及对比,并介绍使用场景。
- 谈谈对接口与回调的理解
- 回调的原理
- 写一个回调demo
- 介绍下SurfView
- RecycleView的使用
- 序列化的作用,以及Android两种序列化的区别
- 差值器
- 估值器
- Android中数据存储方式
(2)Android源码相关分析
- Android动画框架实现原理
- Android各个版本API的区别
- Requestlayout,onlayout,onDraw,DrawChild区别与联系
- invalidate和postInvalidate的区别及使用
- Activity-Window-View三者的差别
- 谈谈对Volley的理解
- 如何优化自定义View
- 低版本SDK如何实现高版本api?
- 描述一次网络请求的流程
- HttpUrlConnection 和 okhttp关系
- Bitmap对象的理解
- looper架构
- ActivityThread,AMS,WMS的工作原理
- 自定义View如何考虑机型适配
- 自定义View的事件
- AstncTask+HttpClient 与 AsyncHttpClient有什么区别?
- LaunchMode应用场景
- AsyncTask 如何使用?
- SpareArray原理
- 请介绍下ContentProvider 是如何实现数据共享的?
- AndroidService与Activity之间通信的几种方式
- IntentService原理及作用是什么?
- 说说Activity、Intent、Service 是什么关系
- ApplicationContext和ActivityContext的区别
- SP是进程同步的吗?有什么方法做到同步?
- 谈谈多线程在Android中的使用
- 进程和 Application 的生命周期
- 封装View的时候怎么知道view的大小
- RecycleView原理
- AndroidManifest的作用与理解
(3)常见的一些原理性问题
- Handler机制和底层实现
- Handler、Thread和HandlerThread的差别
- handler发消息给子线程,looper怎么启动?
- 关于Handler,在任何地方new Handler 都是什么线程下?
- ThreadLocal原理,实现及如何保证Local属性?
- 请解释下在单线程模型中Message、Handler、Message Queue、Looper之间的关系
- 请描述一下View事件传递分发机制
- Touch事件传递流程
- 事件分发中的onTouch 和onTouchEvent 有什么区别,又该如何使用?
- View和ViewGroup分别有哪些事件分发相关的回调方法
- View刷新机制
- View绘制流程
- 自定义控件原理
- 自定义View如何提供获取View属性的接口?
- Android代码中实现WAP方式联网
- AsyncTask机制
- AsyncTask原理及不足
- 如何取消AsyncTask?
- 为什么不能在子线程更新UI?
- ANR产生的原因是什么?
- ANR定位和修正
- oom是什么?
- 什么情况导致oom?
- 有什么解决方法可以避免OOM?
- Oom 是否可以try catch?为什么?
- 内存泄漏是什么?
- 什么情况导致内存泄漏?
- 如何防止线程的内存泄漏?
- 内存泄露场的解决方法
- 内存泄漏和内存溢出区别?
- LruCache默认缓存大小
- ContentProvider的权限管理(解答:读写分离,权限控制-精确到表级,URL控制)
- 如何通过广播拦截和abort一条短信?
- 广播是否可以请求网络?
- 广播引起anr的时间限制是多少?
- 计算一个view的嵌套层级
- Activity栈
- Android线程有没有上限?
- 线程池有没有上限?
- ListView重用的是什么?
- Android为什么引入Parcelable?
- 有没有尝试简化Parcelable的使用?
(4)开发中常见的一些问题
- ListView 中图片错位的问题是如何产生的?
- 混合开发有了解吗?
- 知道哪些混合开发的方式?说出它们的优缺点和各自使用场景?(解答:比如:RN,weex,H5,小 - 程序,WPA等。做Android的了解一些前端js等还是很有好处的);
- 屏幕适配的处理技巧都有哪些?
- 服务器只提供数据接收接口,在多线程或多进程条件下,如何保证数据的有序到达?
- 动态布局的理解
- 怎么去除重复代码?
- 画出 Android 的大体架构图
- Recycleview和ListView的区别
- ListView图片加载错乱的原理和解决方案
- 动态权限适配方案,权限组的概念
- Android系统为什么会设计ContentProvider?
- 下拉状态栏是不是影响activity的生命周期
- 如果在onStop的时候做了网络请求,onResume的时候怎么恢复?
- Bitmap 使用时候注意什么?
- Bitmap的recycler()
- Android中开启摄像头的主要步骤
- ViewPager使用细节,如何设置成每次只初始化当前的Fragment,其他的不初始化?
- 点击事件被拦截,但是想传到下面的View,如何操作?
- 微信主页面的实现方式
- 微信上消息小红点的原理
- CAS介绍(这是阿里巴巴的面试题,我不是很了解,可以参考博客: CAS简介http://blog.csdn.net/jly4758/article/details/46673835)