JAVA高级试题

来源:互联网 发布:淘宝卖家手机登录 编辑:程序博客网 时间:2024/06/03 12:51

面向对象的特征有哪些方面,个人对面向对象思想的理解

Set、List、Map的区别和联系

什么时候使用Linkedhashmap、Concurrenthashmap、Weakhashmap

  • 哪些集合类是线程安全的

抽象类、接口

Java对象的生命周期

答:创建阶段 、 应用阶段 、不可见阶段 、不可达阶段 、收集阶段 、终结阶段、 对象空间重新分配阶段等等,具体参照:Java 对象的生命周期


6、Java Object类中有哪些方法?

答:Object有哪些方法


7、HTTP协议,GET和POST 的区别

答:浅谈HTTP中GET和POST的区别


Collection 和 Collections的区别。


线程和进程有什么区别?



java创建线程后, start 和 run 区别

Thread.start()与Thread.run()有什么区别?


Sleep()、suspend()和wait()之间有什么区别?

什么是死锁

死锁就是两个或两个以上的线程被无限的阻塞,线程之间相互等待所需资源。这种情况可能发生在当两个线程尝试获取其它资源的锁,而每个线程又陷入无限等待其它资源锁的释放,除非一个用户进程被终止。就JavaAPI而言,线程死锁可能发生在一下情况。

●当两个线程相互调用Thread.join()

●当两个线程使用嵌套的同步块,一个线程占用了另外一个线程必需的锁,互相等待时被阻塞就有可能出现死锁。


Java 关键字volatile 与 synchronized 作用与区别


1. 简述一下面向对象的特征,并举例说明你对面向对象的理解?(5分)

面向对象是基于万物皆对象这个哲学观点,把一个帝乡抽象成类,具体就是你吧一个对象的静态特征和动态特征抽象成属性和方法,也就是把一类事务的算法和数据结构封装在一个类之中,程序就是多个对象和互相间的通信组成的。

面向对象具有封装性,继承性,多态性。封装隐蔽了对象内部不需要暴漏的细节,似的内部细节的变动跟外界脱离,只依靠接口进行通信。封装性降低了编程的复杂性。通过继承,使得新建一个类变得容易,一个类从派生类哪里获得其非私有的方法和公用属性的繁琐工作交给了编译器。而继承和实现接口和运行时的类型标定机制所产生的多态,使得不同的类所产生的对象能够对相同的消息做出不同的反映,记得提高了代码的通用性。

总之,面向对象的特性提高了大型程序的重用性和可维护性。

常用设计模式

  • 单例模式:懒汉式、饿汉式、双重校验锁、静态加载,内部类加载、枚举类加载。保证一个类仅有一个实例,并提供一个访问它的全局访问点。

  • 代理模式:动态代理和静态代理,什么时候使用动态代理。

  • 适配器模式:将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

  • 装饰者模式:动态给类加功能。

  • 观察者模式:有时被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

  • 策略模式:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。

  • 外观模式:为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

  • 命令模式:将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化。

  • 创建者模式:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。

  • 抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。



异常分类和处理机制

分类:

  • 运行时异常(Runtime Exception)

  • 受检查异常(Checked Exception)

运行时异常:

  • 必须继承RuntimeException类,

  • 定义方法时不必声明会抛出运行时异常。

  • 调用方法时不必捕获运行时异常。

受检查异常:

  • 不继承自RumtimeException类

  • 定义方法时需要抛出可能会抛出的Checked Exception

  • 调用方法时需要捕获Checked Exception或者继续向上抛出。

逻辑上:

  • 运行时异常:一般不需要或者不知道如何处理此类异常;

  • 受检验异常:一般需要知道如何处理可能发生的异常情况。


StringBuilder内部实现机制

StringBuilder内部有一个字符数组,代码如下

char[] value;   //字符数组int count;      //字符串长度

每一次append操作都是将新的字符串加入到可变长的字符数组中,长度计算方式与ArrayList类似。调用toString()方法时,new一个String对象即可。

public String toString() {        return new String(value, 0, count);// Create a copy, don't share the array}

ps: StringBuffer是线程安全的,StringBuilder是非线程安全的。

Java基础

HashMap和Hashtable的区别

  • HashMap是非线程安全的,Hashtable是线程安全的。

  • HashMap的键值都可以为null,Hashtable的键值都不可以为null值。

  • HashMap继承自AbstractMap类,Hashtable继承自Dictionary类。

ps : Properties类继承自Hashtable类。

Java中的另一个线程安全的与HashMap极其类似的类是什么?同样是线程安全,它与HashTable在线程同步上有什么不同?

HashMap的内部存储结构
Java中数据存储方式最底层的两种结构,一种是数组,另一种就是链表,数组的特点:连续空间,寻址迅速,但是在删除或者添加元素的时候需要有较大幅度的移动,所以查询速度快,增删较慢。而链表正好相反,由于空间不连续,寻址困难,增删元素只需修改指针,所以查询慢、增删快。有没有一种数据结构来综合一下数组和链表,以便发挥他们各自的优势?答案是肯定的!就是:哈希表。哈希表具有较快(常量级)的查询速度,及相对较快的增删速度,所以很适合在海量数据的环境中使用

强引用、软引用、弱引用和虚引用

  • 强引用: 一般的引用都是强引用,即使OutOfMemory也不会回收这部分被把持的引用内存。

  • 软引用(SoftReference): 如果内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被使用。++软引用可以用来实现内存敏感的高速缓存。++

  • 弱引用(WeakReference):弱引用的对象拥有更短暂的生命周期。当垃圾回收期发现只有若引用的对象,不论内存空间足够与否,都会回收它。

  • 虚引用():虚引用不会决定对象的生命周期,如果一个对象仅持有一个虚引用,那么它随时可能被回收。++虚引用主要用来跟踪对象被垃圾回收器回收的活动。++


JVM虚拟机

GC算法有哪些

  • 引用计数

  • 复制

  • 标记-清除

  • 标记-压缩

  • 分代(新生代、老年代、永久代)

垃圾回收器有哪些

  • 串行回收器:新生代串行回收器、老年代串行回收器

  • 并行回收器:新生代ParNew回收器、新生代ParallelGC回收器、老年代ParallelGC回收器

  • CMS回收器:(Concurrent Mark Sweep、并发标记清除)

  • G1回收器(1.7以后代替CMS回收器)

Java 中堆和栈有什么区别?

JVM 中堆和栈属于不同的内存区域,使用目的也不同。

  • 栈常用于保存方法帧和局部变量,而对象总是在堆上分配。

  • 栈通常都比堆小,也不会在多个线程之间共享,而堆被整个 JVM 的所有线程共享

将单项链表逆序排列

将单向链表逆序输出,方法有三种:

  1. 遍历链表,将每个节点的内容存入一个数组中,然后逆序输出数组(最简单的做法)

  2. 使用栈来逆序输出

  3. 直接将链表(指针)逆序然后输出

性能优化

回到顶部

1.如何对 Android 应用进行性能分析

android 性能主要之响应速度 和UI刷新速度。

可以参考博客:Android系统性能调优工具介绍

首先从函数的耗时来说,有一个工具TraceView 这是androidsdk自带的工作,用于测量函数耗时的。

UI布局的分析,可以有2块,一块就是Hierarchy Viewer 可以看到View的布局层次,以及每个View刷新加载的时间。

这样可以很快定位到那块layout & View 耗时最长。

还有就是通过自定义View来减少view的层次。

4、AsyncTask使用在哪些场景?它的缺陷是什么?如何解决?

AsyncTask 运用的场景就是我们需要进行一些耗时的操作,耗时操作完成后更新主线程,或者在操作过程中对主线程的UI进行更新。

缺陷:AsyncTask中维护着一个长度为128的线程池,同时可以执行5个工作线程,还有一个缓冲队列,当线程池中已有128个线程,缓冲队列已满时,如果

此时向线程提交任务,将会抛出RejectedExecutionException。

解决:由一个控制线程来处理AsyncTask的调用判断线程池是否满了,如果满了则线程睡眠否则请求AsyncTask继续处理。




5.讲讲ListView容易引起性能问题的地方,再说一下你有什么优化方案。

6.内存泄露哪几种情况?如何处理?有使用过什么相关的检测工具吗?

6.Android中跨进程通讯有几种方式?

5.Activity的启动模式:Activity的几种LaunchMode及使用场景。

3.说说Android事件分发机制,ViewGroup和View上的分发有什么不同?

横竖屏切换时候Activity的生命周期。

1、不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次

2、设置Activity的android:configChanges="orientation"时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次

3、设置Activity的android:configChanges="orientation|keyboardHidden"时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法



请解释下在单线程模型中Message,Handler,Message Queue,Looper之间的关系。

拿主线程来说,主线程启动时会调用Looper.prepare()方法,会初始化一个Looper,放入Threadlocal中,接着调用Looper.loop()不断遍历Message Queue,

Handler的创建依赖与当前线程中的Looper,如果当前线程没有Looper则必须调用Looper.prepare()。Handler , sendMessage到MessageQueue,Looper不断

从MessageQueue中取出消息,回调handleMessage方法。


6.Android 线程间通信有哪几种方式

1)共享变量(内存)

2)管道

3)handle机制

runOnUiThread(Runnable)

view.post(Runnable)

13.多线程间通信和多进程之间通信有什么不同,分别怎么实现

线程间的通信可以参考第6点。

进程间的通信:bind机制(IPC->AIDL),linux级共享内存,boradcast,

Activity  之间,activity & serview之间的通信,无论他们是否在一个进程内。


23.开发中都使用过哪些框架、平台


16.Handler 机制

参考:android 进程/线程管理(一)----消息机制的框架 这个系类。

回到顶部

17.事件分发机制

android 事件分发机制

5.ANR 是什么?怎样避免和解决 ANR(重要)


3.如何避免 OOM 异常

首先OOM是什么?

当程序需要申请一段“大”内存,但是虚拟机没有办法及时的给到,即使做了GC操作以后

这就会抛出 OutOfMemoryException 也就是OOM

Android的OOM怎么样?

为了减少单个APP对整个系统的影响,android为每个app设置了一个内存上限。

如何避免OOM

减少内存对象的占用

I.ArrayMap/SparseArray代替hashmap

II.避免在android里面使用Enum

III.减少bitmap的内存占用

  • inSampleSize:缩放比例,在把图片载入内存之前,我们需要先计算出一个合适的缩放比例,避免不必要的大图载入。
  • decode format:解码格式,选择ARGB_8888/RBG_565/ARGB_4444/ALPHA_8,存在很大差异。

IV.减少资源图片的大小,过大的图片可以考虑分段加载

内存对象的重复利用

大多数对象的复用,都是利用对象池的技术。

I.listview/gridview/recycleview contentview的复用

II.inBitmap 属性对于内存对象的复用ARGB_8888/RBG_565/ARGB_4444/ALPHA_8

这个方法在某些条件下非常有用,比如要加载上千张图片的时候。

III.避免在ondraw方法里面 new对象

IV.StringBuilder 代替+


2.什么情况下会导致内存泄露

内存泄露是个折腾的问题。

什么时候会发生内存泄露?内存泄露的根本原因:长生命周期的对象持有短生命周期的对象。短周期对象就无法及时释放。

I. 静态集合类引起内存泄露

主要是hashmap,Vector等,如果是静态集合 这些集合没有及时setnull的话,就会一直持有这些对象。

II.remove 方法无法删除set集  Objects.hash(firstName, lastName);

经过测试,hashcode修改后,就没有办法remove了。

III. observer 我们在使用监听器的时候,往往是addxxxlistener,但是当我们不需要的时候,忘记removexxxlistener,就容易内存leak。

广播没有unregisterrecevier

IV.各种数据链接没有关闭,数据库contentprovider,io,sokect等。cursor

V.内部类:

java中的内部类(匿名内部类),会持有宿主类的强引用this。

所以如果是new Thread这种,后台线程的操作,当线程没有执行结束时,activity不会被回收。

Context的引用,当TextView 等等都会持有上下文的引用。如果有static drawable,就会导致该内存无法释放。

VI.单例

单例 是一个全局的静态对象,当持有某个复制的类A是,A无法被释放,内存leak。


1.Activity的启动过程(不要回答生命周期) 
http://blog.csdn.net/luoshengyang/article/details/6689748

2.Activity的启动模式以及使用场景 
(1)manifest设置,(2)startActivity flag 
http://blog.csdn.net/CodeEmperor/article/details/50481726 
此处延伸:栈(First In Last Out)与队列(First In First Out)的区别



10.进程间通信的方式 
(1)AIDL,(2)广播,(3)Messenger 

3.Service的两种启动方式 
(1)startService(),(2)bindService() 
http://www.jianshu.com/p/2fb6eb14fdec

4.Broadcast注册方式与区别 
(1)静态注册(minifest),(2)动态注册 

.MVP框架(必问) 
http://blog.csdn.net/lmj623565791/article/details/46596109 
此处延伸:手写mvp例子,与mvc之间的区别,mvp的优势

14.讲解一下Context 
http://blog.csdn.net/lmj623565791/article/details/40481055


20.WebView与js交互(调用哪些API) 
http://blog.csdn.net/cappuccinolau/article/details/8262821/


21.内存泄露检测,内存性能优化 
http://blog.csdn.net/guolin_blog/article/details/42238627 
这篇文章有四篇,很详细。 
此处延伸: 
(1)内存溢出(OOM)和内存泄露(对象无法被回收)的区别。 
(2)引起内存泄露的原因