Skip to content

Latest commit

 

History

History
411 lines (265 loc) · 12.4 KB

面试.md

File metadata and controls

411 lines (265 loc) · 12.4 KB

1. RxJava2 比RxJava 1 有什么区别,主要升级。

1). 背压 

2). 新增Flowable

3). 不支持null,异常

4). 新增Maybe
 
5). ActionN、FuncN
	
	Action0 -> Action
	Action1 -> Consumer
	Action2 ->BiConsumer
	Action3~9 不用
	ActionN Consumer<Object[]>
	
	Func  -> Function
	Func2 -> BiFunction
	Func3~9 -> Function3~9
	FuncN -> FUnction<Object[],R>

6). Observable.OnSubscribe -> ObservableOnSubscribe
	使用ObservableEmitter替代Subscriber向Observer发送数据
	
7). Observable.Transformer -> ObservableTransformer
		FlowableTransformer
		
8). Subscription -> Disposable

9). first()用法改变

10). toBlocking().y -> blockingY() 

11). rx.xxx -> io.reactivex.xxx   包名

2. 四种引用类型

强、软、弱、虚

从JDK 1.2版本开始,把对象的引用分为4种级别

3. Android的进程级别

前台、可见、服务、后台、空

  • 前台

    用户当前正在做的事情需要这个进程。如果满足下面的条件之一,一个进程就被认为是前台进程:

    这个进程拥有一个正在与用户交互的Activity(这个Activity的onResume()方法被调用)。

    这个进程拥有一个绑定到正在与用户交互的activity上的Service。

    这个进程拥有一个前台运行的Service(service调用了方法startForeground()).

    这个进程拥有一个正在执行其任何一个生命周期回调方法(onCreate(),onStart(),或onDestroy())的Service。

    这个进程拥有正在执行其onReceive()方法的BroadcastReceiver。

  • 可见

    这个进程拥有一个不在前台但仍可见的Activity(它的onPause()方法被调用)。当一个前台activity启动一个对话框时,就出了这种情况。

  • 服务

    正在运行的,不在上述两种状态的service 例如: 音乐播放,下载

  • 后台

    不可见状态的activity进程,onstop被调用

    这样的进程们不会直接影响到用户体验,所以系统可以在任意时刻杀了它们从而为前台、可见、以及服务进程们提供存储空间。通常有很多后台进程在运行。它们被保存在一个LRU(最近最少使用)列表中来确保拥有最近刚被看到的activity的进程最后被杀。如果一个activity正确的实现了它的生命周期方法,并保存了它的当前状态,那么杀死它的进程将不会对用户的可视化体验造成影响。因为当用户返回到这个activity时,这个activity会恢复它所有的可见状态。

  • 一个进程不拥有入何activity组件。

    唯一原因是做为缓存以改善组件再次于其中运行时的启动时间。经常被杀死,保持进程缓存和系统内核缓存之间的平衡。

4. js 如何与 native 交互

  • js调用java
   
   // html代码
         <button onClick="window.androidShare.jsShareMethod('param')">js调java</button>
         
   //java代码
        mWebView.getSettings().setJavaScriptEnabled(true);
        mWebView.addJavascriptInterface(new WebInterface(), "androidShare");
        
         private class WebInterface {
                @JavascriptInterface
                public void jsShareMethod(String result) {
                }
            }
            
  • java调用js

实现Android调用JS脚本是非常简单的,直接Webview调用loadUrl方法,里面是JS的方法名,并可以传入参数,javascript:xxx()方法名需要和JS方法名相同

    //java代码
    contentWebView.loadUrl("javascript:javacalljs()");
    
    //html代码
    <script>
        function javacalljs(){
        alert("js")
    </script>
    

5. glide(fresco/Picasso)加载图片遇到的坑(大图片),对比

  • glide默认使用RGB_565,没有缓存透明度
  • Picasso缓存的是全尺寸的,而Glide缓存的是跟ImageView尺寸相同的。

6. Mediaplayer生命周期、bilibili

exception

7. recyclerview添加headerview、footview

通过itemype

8. 抽象类,设计模式中用到抽象类的都有哪几种

抽象类可以有构造函数,但是不能实例化

模板模式、抽象工厂、装饰、策略等

9. java中异常分几种,举例

  • Checked Exception

              除了特殊子类RuntimeException体系的,只要是Exception和其子类都是。这种问题一旦出现,希望在编译时就进行检测,让这种问题有对应的处理方式
              IOException
    
  • runtime exception

              这种问题的发生,让功能无法继续,运算也无法进行,更多是因为调用的原因导致的。或者引发程序内部状态改变,导致异 常。这种问题一般不处理,直接编译通过,在运行时,调用者调用时引发异常从而程序强制停止,此时调用者即可对异常进行修正。
              NullpointerException,IndexOfBoundsExcetion
    

exception

10. Handler机制

同一个线程下的handler共享一个looper对象,消息中保留了对handler的引用,只要有消息在队列中,那么handler便无法被回收,如果handler不是static,那么使用Handler的Service和Activity就也无法被回收,即便它们的ondestroy方法被调用。这就可能导致内存泄露。当然这通常不会发生,除非你发送了一个延时很长的消息。

handler

11. HandlerThread

内部加入Looper的Thread

    HandlerThread mThread = new HandlerThread("hanlder");
    //启动
    mThread.start();
    
    
    //释放资源
    mThread.quit() ;
    

12. AsyncTask实现的原理

AsyncTask

13. rxJava(三个网络请求怎么处理)

  • merge/zip
	Observable ob1 = Observer.from(1);
	Observable ob2 = Observer.from(2);
	
	Observable.merge(ob1,ob2)
				.subscribe( new Observer(){
				//onNext
				
				//onError()
				
				//onCompleted()
				}
				);
  • join/combineLatest
  • and/then/when

14. 方法加final

不能被子类重写,不能使abstract

15. java中新的集合

Apache common.collections中新增了几个集合类

  • BidiMap

双向的,通过key/value互查

  • MultiMap

一个key指向一组对象,add(),remove()相同,get()时,返回Collection 实现一对多

  • LazyMap

key/value不存在,调用的时候创建,一般需要使用LazyMap.decorate(Map,Factory)的方式来创建

16. MVC在Android中引用

17. targetSDKVersion、minSDKVersion

  • build target

ec里面project.properties文件里target=android-18,使用sdk中platforms目录下Android-18目录中的android.jar as中设置compileSdkVersion

  • minSDKVersion

默认1,向下兼容的最小版本,如果目标手机的api 小于这个值,系统会阻止安装并报错 INSTALL_FAILED_OLDER_SDK

  • targetSDKVersion

目标API Level,不设置,默认跟min相同,在运行应时起作用,检测是不是要以兼用模式运行

  • maxSdkVersion

2.0前程序安装时、系统升级后起作用 官方不推荐使用

18. 数据库升级,增加字段

数据库升级不保留原有信息,需要手动讲库中的数据备份,将字段加入后,迁移数据

19. Handler.post(Runnable)

post 一个线程进入到MessageQueue中

20. 单链表逆序输出

  • 迭代方式
    private void reverse(Node node){
        if(node.next){
            reverse(node.next);
        }
        print(node.item);
    }

21. ArrayList、LinkedList原理,增删实现

  • ArrayList

实际上就是构建一个可变长度大小数组对象,每个ArrayList对象维护一个对象数组,初始化空构造器默认初始化大小为10的对象数组,当然,也可以自定义长度。

  1. add操作

1). 加入元素之前,为了确保对象长度足够大,ensureCapacityInternal(size + 1),增加一个元素后,长度加一

    /**
     * Appends the specified element to the end of this list.
     *
     * @param e element to be appended to this list
     * @return <tt>true</tt> (as specified by {@link Collection#add})
     */
    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

2). 扩容前判断对象数组是否为空,空则把默认大小(10)与预计大小做个比较,取最大的作为扩容后对象数组长度

    private void ensureCapacityInternal(int minCapacity) {
        if (elementData == EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);
    }

3). 判断当前初始化对象数组的长度与目标大小,是否需要扩容,扩容需要调用grow()方法

    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

4). 需要扩容的情况下,新容量为原容量的1.5倍 (int newCapacity = oldCapacity + (oldCapacity >> 1);) 扩容后重新生成一个数组

    /**
     * Increases the capacity to ensure that it can hold at least the
     * number of elements specified by the minimum capacity argument.
     *
     * @param minCapacity the desired minimum capacity
     */
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
  1. remove操作

    1). 判断索引是否超出边界,报异常

    2). 删除位置后面的元素向前移动

 /**
     * Removes the element at the specified position in this list.
     * Shifts any subsequent elements to the left (subtracts one from their
     * indices).
     *
     * @param index the index of the element to be removed
     * @return the element that was removed from the list
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    public E remove(int index) {
        if (index >= size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));

        modCount++;
        E oldValue = (E) elementData[index];

        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // clear to let GC do its work

        return oldValue;
    }

  • LinkedList

底层实现是一个双向链表,add/remove操作不做过多解释

  • 总结

    • ArrayList 基于动态数据的数据结构,LinkedList基于链表的数据结构
    • 随机访问的get()/set(),ArrayList要优于LinkedList
    • add()/remove(),LinkedList要优于ArrayList
    • 数组中间位置增加删除,顺序访问的话,可以考虑LinkedList
    • 随机访问使用ArrayList

22. HashMap实现原理,遍历方式

http://www.importnew.com/7099.html

23. MVP、MVC

mvc

MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示。

  • MVP优点
  1. 模型与视图完全分离,我们可以修改视图而不影响模型;
  2. 可以更高效地使用模型,因为所有的交互都发生在一个地方——Presenter内部;
  3. 我们可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁;
  4. 如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试)。

24. 静态方法加synchronized,普通方法synchronized

  • 非静态 锁针对的是对象,不是方法,如果在多线程中创建了两个对象, 那么就不起作用了
  • 静态 实际上是给类加锁(同class 锁效果)

25. 内存泄漏、内存溢出

大量的内存泄露会导致内存溢出(oom)

7月27日面试