2018年三四月份---Android面试集锦

本面试集锦主要包含:数据库、项目、基本算法、Java基础知识和高级、Android知识点。

【基础知识】

1、线程和进程的区别
    线程
        cpu调度的最小单位。
        拥有自己的运行栈和程序计数器、栈。
        是进程的组成部分,必须拥有一个父进程。
    
    进程
        进程是系统进行资源分配和调度的一个单位;
        每个进程都有独立的代码和数据空间。
        1个进程包含1-n个线程。
        
    一个线程可以创建和撤销另一个线程;
    同一个进程中的多个线程之间可以并发执行.
    相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。


2、进程之间的通信方式
    bundle
    file
    messager
    aidl
    socket
    广播


3、多线程
    好处和作用
    并发处理
    创建方式
    关键方法
    生命周期


4、栈、队列操作
    栈:
        empty():测试栈是否为空
        peek():查看栈顶部的对象,但是不移除它。
        pop():返回并移除栈顶部的这个对象。
        push(E item):把对象压入到栈顶部。
        search(Object o):返回对象在栈中的位置。
        
    队列:


5、oom异常如何避免,内存溢出如何检查
    cursor的关闭
    流的关闭
    bitmap的回收
    context的使用
    static的使用
    内部类的使用
    广播的反注册
    handler的移除


6、设计模式
    观察者模式
    工厂模式
    单例模式
    建造者模式


7、同步的单例,如何在单例里用Context还不引起内存泄漏
    使用applicationcontext,生命周期和应用一样长。




【网络】


1、浏览器中输入美团网,之后的会经过哪些步骤
    首先发给DNS服务器,进行域名解析,得到IP地址后生成针对目标Web服务器的HTTP请求报文,
    然后报文由TCP协议负责传输,为了方便通信,HTTP请求报文被分为报文段,
    然后每个报文段可靠的传输给对方,
    然后报文段由IP层负责一边中转一遍传送,服务器收到报文段后重组报文段,
    然后由应用层的HTTP协议处理请求的内容,请求的结果以同样的方式进行回传。


2、点击一个url的完整过程、三次握手
    1、查询DNS(域名解析),获取域名对应的IP地址;
    2、浏览器与服务器建立tcp连接(三次握手);
    3.浏览器向服务器端发送http请求(请求和传输数据)
    4.服务器接受到这个请求后,根据路径参数,经过后端的一些处理生成html页面代码返回给浏览器
    5.浏览器拿到完整的html页面代码开始解析和渲染,如果遇到引用的外部css、图片等静态资源,他们同样也是一个个htpp请求,重复上面的步骤。
    6.浏览器根据拿到的资源对页面进行渲染,最终把一个完整的页面呈现给用户。
    
3、Http各种协议所在的层


4、http的状态码
    HTTP状态码的作用是:Web服务器用来告诉客户端,发生了什么事。
    
    200     OK     服务器成功处理了请求(这个是我们见到最多的)
    301/302 Moved Permanently(重定向)请求的URL已移走。Response中应该包含一个Location URL, 说明资源现在所处的位置
    304     Not Modified(未修改)客户的缓存资源是最新的,要客户端使用缓存
    404     Not Found    未找到资源
    501     Internal Server Error  服务器遇到一个错误,使其无法对请求提供服务


5、http协议传输中,post get的区别
    post:
        1、用来向目的服务器发出请求,要求它接收被附在请求后的实体,并把它当做请求队列中请求URL所指定资源的附加新子项。
        2、POST方式将表单内各个字段和内容放置在HTML HEADER中一起传送到Action属性所指定的URL地址,用户是看不到这个过程的。
        3、POST方式传送的数据量比较大,一般被默认为没有限制,但是根据IIS的配置,传输量也是不同的。
        4、POST方式在服务器端用Request.Form获取提交的数据。
        5、POST方式传输的数据安全性较高,因为数据传输不是明显显示的。
    get:
        1、GET方式是以实体的方式得到由请求URL所指定资源的信息。
        2、请求的数据会附加在URL之后,以?分隔URL和传输数据,多个参数用&连接。
                URL编码格式采用的是ASCII编码,而不是Unicode,即所有的非ASCII字符都要编码之后再传输。
        3、因为URL的长度限制,GET方式传输的数据大小有所限制,传送的数据量不超过2KB。
        4、GET方式服务器端用Request.QueryString获取变量的值。
        5、GET方式传输的参数安全性低,因为传输的数据会显示在请求的URL中。


6、https加密原理


7、http版本1.0、1.1和2.0区别


8、请求和响应header里有什么


9、cookies和session作用,如何使用,为什么要用这个机制


10、http与https有什么区别,https如何确保通信安全


11、websocket和socket是什么?异同?


12、osi是什么,为什么分层? 分几层,每层都是干嘛的


13、一次网络请求的完整过程


14、Tcp/udp相关知识:


15、tcp3次握手是什么,有什么作用,具体过程,为什么一定要3次


16、tcp4次挥手具体过程


17、tcp与udp区别,各自的应用场景


18、Tcp是如何保证可靠性传输的


19、如何设计在 UDP 上层保证 UDP 的可靠性传输


20、tcp滑动窗口是什么,有什么用?
    


【java】


1、wait和sleep对资源的释放与否
    wait  释放锁
    sleep  不释放
    
2、用java语言实现生产者、消费者
    
3、arraylist,hashmap这些底层实现原理
    ArrayList  数组
    HashMap    数组  链表
    linkedlist   链表
    
4、ArrayList、LinkedList区别。Map有哪几个子类
    ArrayList  底层是数组   查询快  增删慢   线程不安全
    linkedlist 底层是链表   增删快  查询慢   线程不安全
    map:
        HashMap
        treemap
    
5、hashmap和hashtable,hashSet区别
    hashmap  可以存储null值和null键   底层是数组  链表结构   线程不安全的,效率高
    HashTable  不可以存储null值和null键   底层是哈希表    线程安全的,效率低
    HashSet   底层是哈希表    无序   高效   线程不安全的   通过hashcode和equals方法,保证唯一性
    
6、hashcode的实现方法,哈希冲突及解决方案
    实现方法:
        1 如果两个对象相同,那么它们的hashCode值一定要相同。
            也告诉我们重写equals方法,一定要重写hashCode方法,也就是说hashCode值要和类中的成员变量挂上钩,
            对象相同–>成员变量相同—->hashCode值一定相同。
        2 如果两个对象的hashCode相同,它们并不一定相同,这里的对象相同指的是用eqauls方法比较。
    解决方案:
        拉链法
        
7、GC机制什么时候会启动?
    显示调用
    内存不足
    系统空闲


8、synchronized的用法,和wait notify的使用
    线程安全,处理并发:
        同步方法
        同步代码块
    
    wait()
        a.属于Object类;
        b.可以指定时间,也可以不指定;当时间到时,或者使用notify( )或notifyAll( )方法后,会醒来;
        c.在同步方法中,会释放锁;
        d.使用时不必捕获异常;
        
    notify()
        调用某个对象的notify()方法能够唤醒一个正在等待这个对象的monitor的线程,
        如果有多个线程都在等待这个对象的monitor,则只能唤醒其中一个线程;
    
    notifyall()
        调用notifyAll()方法能够唤醒所有正在等待这个对象的monitor的线程;
    
9、synchronized 加载类方法和对象方法上时有什么不同
        非静态方法:用this当做参数;
                    给对象枷锁;
        静态方法:1、用类名.class当参数 2、通过实例的getClass()方法当参数。
                    相当于在类上加锁(*.class 位于代码区,静态方法位于静态区域,这个类产生的对象公用这个静态方法,所以这块
                    内存,N个对象来竞争), 这时候,只要是这个类产生的对象,在调用这个静态方法时都会产生互斥.


10、java中的作用域/权限(public、protected、default、private)
        (1)public:可以被所有其他类所访问。
        (2)private:只能被自己访问和修改。
        (3)protected:自身,子类及同一个包中类可以访问。
        (4)default(默认):同一包中的类可以访问,声明时没有加修饰符,认为是friendly。


11、java中那些地方用到泛型,举例说出泛型的好处
        好处:
            运行时期的问题,提到了编译时期;
            避免了强制转换的问题;


12、内部类与外部类的关系,内部类的static与非static的区别
        1、内部类可以直接访问外部类中的成员。而外部类想要访问内部类,必须要建立内部类的对象。
        2、如果内部类被静态修饰,相当于外部类,会出现访问局限性,只能访问外部类中的静态成员。
           注意;如果内部类中定义了静态成员,那么该内部类必须是静态的。


13、JAVA虚拟机的内存回收大概的策略有哪些
    垃圾回收机制算法
        引用计数法
        根搜索算法
        标记清除
        标记整理
        generation算法
        
14、Java的4种引用有哪些,作用,使用场景
    强引用
    软引用
    弱引用
    虚引用
    
15、Person P = new Person() 这个过程发生了什么?
    1:先将硬盘上指定位置的Person.class文件加载进内存。
    2:执行main方法时,在栈内存中开辟了main方法的空间(压栈-进栈),然后在main方法的栈区分配了一个变量p。
    3:在堆内存中开辟一个实体空间,分配了一个内存首地址值。
    4:在该实体空间中进行属性的空间分配,并进行了默认初始化。
    5:对空间中的属性进行显示初始化。
    6:进行实体的构造代码块初始化。
    7:调用该实体对应的构造方法,进行构造方法初始化。
    8:将首地址赋值给p ,p变量就引用了该实体。(指向了该对象)


16、简述Java类加载过程
    加载  验证  准备   解析  初始化  使用  卸载


17、Classloader是什么,工作原理,好处,如何修改加载流程    :类加载器,双亲委托机制,自定义ClassLoader
    


18、获取class对象的几种方法
     1.Object类-->getClass( );
     2.任何数据类型(包括基本数据类型)都有一个"静态的class属性",可以获取它的Class对象;
        推荐使用xx.class方式,不会初始化类
     3.Class类"静态方法--forName(String 全名限定的类名)"-----常用------


19、反射是什么,有什么用,实现原理,同样的代码反射为什么比非反射执行的速度慢。
        动态的获取和调用一个类的属性或者方法。
        类加载机制,加载字节码到内存,获取这个对象的相关属性和方法。
        
        反射包括了一些动态类型,所以JVM无法对这些代码进行优化。因此,反射操作的效率要比那些非反射操作低得多。
        我们应该避免在经常被 执行的代码或对性能要求很高的程序中使用反射。


20、Java内存泄露定义,常见的内存泄露例子。
    生命周期结束的对象,无法被垃圾回收机制回收。
    本质就是长生命周期持有短生命周期的对象,导致短生命周期的对象不能被垃圾回收




21、Jvm内存分区,内存的分配和回收过程,内存回收标准是什么?
        1. 线程计数器:
                一块较小的内存空间,每个线程都有自己的线程计数器,用于完成不同线程上下文切换,
                如果调用的是本地方法,pc寄存器不存储任何信息。
        2. 堆区(Heap):
                所有线程共享堆空间,主要存放对象实例与数组,new创建的对象内存都在此分配,
                因为线程共享,所以需要加锁造成new的开销比较大。
        3. 栈区(stack):
                栈与线程计数器一样,都是线程独有,栈的生命周期与线程的生命周期同步。
                每一次方法执行时就会同时创建一个栈帧,用于存储局部变量和操作数栈。
                每一个方法调用到执行完毕就对应着栈桢在栈区入栈到出栈的过程。
        4. 本地方法栈:
                本地方法执行的时候,进入本地方法栈。
        5. 方法区:
                和堆区一样,都是线程共享。
                存放JVM加载的类型信息,如类型基本信息,常量,方法表等等。


22、Java内存模型,为什么会出现变量读取不一致的情况?
        并发   内存共享性


23、Volatile是什么,作用,使用场景,实现原理 :内存屏障
     a.volatile关键字为域变量的访问提供了一种免锁机制,
     b.使用volatile修饰域相当于告诉虚拟机该域可能会被其他线程更新,
     c.因此每次使用该域就要重新计算,而不是使用寄存器中的值
     d.volatile不会提供任何原子操作,它也不能用来修饰final类型的变量


24、Java同步机制是什么?Synchronized实现原理?对象锁(方法锁)和类锁的区别?
        处理并发问题的机制,防止同一时间有多个线程访问同一个资源。
        在Java中的Object类对象中,都是带有一个内存锁的,在有线程获取该内存锁后,其它线程无法访问该内存,从而实现Java中简单的同步、互斥操作。
        对象锁,锁的是内存区域,当前类的一个对象。类锁,锁的是类的字节码文件。


25、synchronzied与lock异同?
    synchronized:
        java关键字;
        1、以获取锁的线程执行完同步代码,释放锁 2、线程执行发生异常,jvm会让线程释放锁
        无法判断锁的状态
        适用于少量同步
        
    lock:
        一个类;
        在finally中必须释放锁,不然容易造成线程死锁。
        可以判断锁的状态;
        适用于大量同步


26、new了很多A类的对象实例,一个线程池的多个线程不断去操作A对象被synchronized修饰的方法,会同步操作吗?如果该方法是static的,又会怎么样?


27、java中的四种线程池区别,以及常见应用场景。
    newCachedThreadPool:
    底层:返回ThreadPoolExecutor实例,corePoolSize为0;maximumPoolSize为Integer.MAX_VALUE;keepAliveTime为60L;
          unit为TimeUnit.SECONDS;workQueue为SynchronousQueue(同步队列)
    通俗:当有新任务到来,则插入到SynchronousQueue中,由于SynchronousQueue是同步队列,
          因此会在池中寻找可用线程来执行,若有可以线程则执行,若没有可用线程则创建一个线程来执行该任务;
          若池中线程空闲时间超过指定大小,则该线程会被销毁。
    适用:执行很多短期异步的小程序或者负载较轻的服务器


    newFixedThreadPool:
    底层:返回ThreadPoolExecutor实例,接收参数为所设定线程数量nThread,corePoolSize为nThread,
          maximumPoolSize为nThread;keepAliveTime为0L(不限时);unit为:TimeUnit.MILLISECONDS;
          WorkQueue为:new LinkedBlockingQueue<Runnable>() 无解阻塞队列
    通俗:创建可容纳固定数量线程的池子,每个线程的存活时间是无限的,当池子满了就不在添加线程了;
          如果池中的所有线程均在繁忙状态,对于新任务会进入阻塞队列中(无界的阻塞队列)
    适用:执行长期的任务,性能好很多


    newSingleThreadExecutor:
    底层:FinalizableDelegatedExecutorService包装的ThreadPoolExecutor实例,corePoolSize为1;maximumPoolSize为1;
          keepAliveTime为0L;unit为:TimeUnit.MILLISECONDS;workQueue为:new LinkedBlockingQueue<Runnable>() 无解阻塞队列
    通俗:创建只有一个线程的线程池,且线程的存活时间是无限的;
          当该线程正繁忙时,对于新任务会进入阻塞队列中(无界的阻塞队列)
    适用:一个任务一个任务执行的场景


    NewScheduledThreadPool:
    底层:创建ScheduledThreadPoolExecutor实例,corePoolSize为传递来的参数,maximumPoolSize为Integer.MAX_VALUE;keepAliveTime为0;
          unit为:TimeUnit.NANOSECONDS;workQueue为:new DelayedWorkQueue() 一个按超时时间升序排序的队列
    通俗:创建一个固定大小的线程池,线程池内线程存活时间无限制,线程池可以支持定时及周期性任务执行,
          如果所有线程均处于繁忙状态,对于新任务会进入DelayedWorkQueue队列中,这是一种按照超时时间排序的队列结构
    适用:周期性执行任务的场景


28、Java的final关键字的作用
    修饰类,这个类不能被继承,类中的成员方法,也隐式的被置为final类型。
    修饰方法,该方法不能被子类继承和重写。
    修饰变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;
              如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。


29、Java中内部类为什么可以访问外部类
        内部类对象的创建依赖于外部类对象;
        内部类持有一个外部类的引用。(this、class)
        
30、多态是什么,有什么好处?重载与重写
    面向对象三大特征之一
    提高代码的可维护性和扩展性。
    
    重载:
        方法名相同,但方法参数不同,个数不同
        返回值类型  可相同  也可不同
        java多态的一种体现。
    
    重写:
        子类继承父类的方法。
        对父类方法进行重新定义。


31、死锁的4个条件,怎么避免死锁
        1、互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用
        2、不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。
        3、请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有。
        4、循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样就形成了一个等待环路。
    
    处理死锁的基本方法
        1.预防死锁:通过设置一些限制条件,去破坏产生死锁的必要条件
        2.避免死锁:在资源分配过程中,使用某种方法避免系统进入不安全的状态,从而避免发生死锁
        3.检测死锁:允许死锁的发生,但是通过系统的检测之后,采取一些措施,将死锁清除掉
        4.解除死锁:该方法与检测死锁配合使用


32、手写生产者/消费者模式


33、hashMap的实现原理
    数组 + 链表


34、hashcode和equals方法是干嘛的,hashcode码原理及实现
    比较对象是否相等,先比较hashcode值是否相等,在比较equals是否相等。


35、object类里有哪些方法
    hashcode()
    equals()
    notify()
    notifyall()
    clone()
    wait()
    tostring()
    getClass()


36、hashmap原理,查询速度优化,红黑树和其他二叉树区别
    数组 + 链表  (寻址快,插入和删除快)


37、面向对象设计6原则
    单一职责原则
    开闭原则
    里氏替换原则
    依赖倒置原则
    接口隔离原则
    迪米特原则


38、设计模式:手写3种单例、手写观察者。


39、工厂、策略、模板、代理、外观、装饰
    


【android】


1、热修复的一些基本原理
    类加载机制
    双亲委托
    多dex安装包
    
2、四大组件有哪些
    activity
    service
    broadcastreceiver
    ContentProvider


3、activity、fragment生命周期
    activity : oncreate  onstart  onresume  onpause  onstop   onrestart   ondestroy  
    fragment:  onattach  oncreate   oncreateview   onactivitycreated   onstart  onresume  onpause  onstop  ondestroyview  ondestroy   ondetach
    
4、两个Activity之间跳转生命周期的切换
        A--->B
            A: onpause-->                      onstop
            B:  onCreate--> onstart--> onresume
        B-->A
            A:onrestart  onstart  onresume
            B:onpause   onstop    ondestroy
        
5、activity启动方式
        standard
        singletop       推送新闻界面
        singletask       浏览器首页
        singleinstance     拨号界面
    
6、service的启动方式
        startService();   oncreate()   onstartcommand   ondestroy
        bindService();    oncreate()   onbind()   onunbind()   ondestroy()
    
7、activity中如何调用service中的方法
        参考:https://www.cnblogs.com/zhujiabin/p/6030955.html
    简单来说就是bindservice,就能·获取到service实例,然后就能调用service
8、service和主程序UI怎么交互
        参考:http://blog.csdn.net/yihongyuelan/article/details/7216188
    广播
    使用handler
9、Android系统里面的DVM进程,apk进程与linux进程是否是同一范畴的概念
        参考:https://www.nowcoder.com/questionTerminal/f943084247dc41789c88c524766648c6
    是同一概念
10、怎么防止服务被杀死(进程保活)
        参考:http://www.orzangleli.com/2016/08/22/Android%20Service%20%E6%8C%81%E4%B9%85%E8%BF%90%E8%A1%8C%E4%B8%8D%E8%A2%AB%E6%9D%80%E6%AD%BB%E6%96%B9%E6%B3%95%E6%80%BB%E7%BB%93/
        
        提高优先级
            像素activity(监听屏幕开关的广播)
            notification(前台进程)
                        
        杀死后拉起
            系统广播(开关机、拍照)
            三方广播(SDK)
            service特性 (sticky。。。。)
            利用native进程
11、之前项目中是如何处理图片的。如果程序发生OOM了或者发生其他严重内存问题了,如何利用DDMS里面的检测工具发现问题


【图片缓存机制,Lru算法,Lru原理?除了Lru,你还知道哪些缓存算法】


【如果有一张很大size的图片需要加载到手机里怎么办】
【android异步消息处理机制,handler AsyncTask源码】
【Android中为什么主线程不会因为Looper.loop()里的死循环卡死】
【handlerThread是什么】
【IntentService】
【view事件如何分发与传递】
ListView中按button然后上下滑动,button是否取消特效?
为什么?这里面事件是如何传递的
【view绘制机制】
在onMeasure中传递的参数是什么
【Activity的4种启动模式有了解么?各自的含义是什么?】
【startactivityforresult的时候,比如A startB activity,
A activity被回收,B回来的时候的A和B的生命周期各自是什么?】
【onSaveInstance和onPause、onStop顺序】
【onResume和onStart区别】
【如何判断onResume时已经渲染好】
【service是什么,作用】
【service和activity交互】
【service保活】
【app自动重启】
【APK包含了哪些东西,打包过程是什么】
【APP启动流程】
【ListView性能优化,以及ListView的各种原理】
【RecyclerView优点,原理】
【CoordinatorLayout、CollapsingToolbarLayout原理以及使用】
【插件化】
【热修复,差分包】
【如何挑选同类型第三方jar】
mvc与mvp模式都是什么,区别
sp进程、线程安全,2个方法异同
listview 缓存原理,receclerview原理
插件化


==============================================================================================


1、View绘制原理
    onmeasure
    onlayout
    ondraw


2、View触摸事件体系
    dispatch
    onintercept
    ontouchevent


3、点击ListView的Item,并移动,到ListView滚动,事件分发的过程


4、TextView文字变化,触发了什么
    
5、listview滚动时translation是否改变


6、listview加载图片会有什么问题,如果引起图片错位是什么原因导致的?怎么解决?
    oom  
    图片错位:
        原因:
            复用机制
        解决方法:
            对imageview设置tag,并预设一张图片。


7、如何对一个ListView的滑动做优化
    使用viewholder;
    getview()方法中不做耗时操作;
    图片加载采用三级缓存;
    滑动过程中不加载,停止才加载;
    分页加载
    
8、多屏适配
    图片适配
    代码适配
    dp、sp
    布局适配


9、android布局优化有哪些
    减少布局层次,去除不必要的父布局
    善用相对布局
    善用布局标签
        include
        merge
        viewstub
    textview的drawable属性
    使用最新的布局方式:ConstaintLayout
    利用AndroidStudio的Lint工具寻求可能优化布局的层次


10、volley、
    1.当一个Request请求添加到RequestQueue请求队列中,Volley就开始工作了。
        RequestQueue请求队列中持有一个CacheDispatcher缓存管家和一组NetworkDispatcher网络管家。
    2.RequestQueue会先叫来CacheDispatcher缓存管家,让他去看看,当前请求的数据在没在cache中。
        2.1.当前的数据在cache中,那就把数据从cache中取出来,然后经过一番加工,将加工好的数据交付给主线程
        2.2.当前数据没在cache中,进行第3步


    3.进行到了这一步,那肯定是数据没有在缓存中,那只能去网络中获取了,这时候RequestQueue会叫来NetworkDispatcher,
        NetworkDispatcher可是有一帮呢,其实这是一个线程池,默认情况下会启动4个线程去网络下载数据。
        所以RequestQueue把当前闲着的NetworkDispatcher叫来,给他们分配任务。
    4.拿到任务的NetworkDispatcher就会去网络上下载数据了,与此同时,他会判断下载到的数据能否写入到cache缓存中,
        如果可以的话就写入cache,以便于下一次直接从cache中获取到数据。最后,将数据加工,交付给主线程。


11、gson解析




【数据库】
    1、数据库的增删查改
        增:insert into student (name, phone) values (‘张三’, ‘110’)
        删:delete from student where name=‘张三’
        改:update student set phone=‘119’ where name=‘张三’
        查:select * from student where name=‘张三’
                                
    2、表中加俩字段,数据库如何升级,不能删除数据库
        //1 新建临时表
            generateTempTables(db, daoClasses);
        //2 创建新表
            createAllTables(db, false, daoClasses);
        //3 临时表数据写入新表,删除临时表
            restoreData(db, daoClasses);
        
    3、数据库设计3范式
        原子性,数据不可再分
        唯一性,消除部分依赖
                将部分依赖转换成完全依赖,拆表!
                将原来存在部分依赖的表拆分,简单来说就是该表主键有几个字段,就拆成(几个+1)的表,
                前几个字段将分别作为其所在表的唯一主键,即成为完全依赖模式。
                最后一个表为之前的那几个字段并存的联合主键。
                用于维护表与表之间的关系。
        独立性,消除传递依赖
                将传递依赖部分提取出来,拆表!
                将原来的表中存在传递依赖的字段提取出来,新建一个表。
                该新表的主键即为原表中被依赖的那个字段。此字段在原来的表中将作为外键而存在。
    
    4、如何备份,升级数据库(不能删库重建)
        sqlite> .backup 'backup.db'


    5、索引的原理与作用




【项目】
1、图片加载框架优劣比较,以及之前项目选用加载框架时候的考虑
    最佳答案:https://github.com/soulrelay/ImageLoaderUtil
    Glide
    volley
2、如何自己实现一个加载图片的框架,应该考虑哪些方面
    图片缓存、
    线程池的数量、
    压缩、
    API的简洁
    listview导致的错位等
3、做一个能放大缩小的图片查看器,加载一张巨大的图片,怎么做?
    BitmapRegionDecoder主要用于显示图片的某一块矩形区域;
https://blog.csdn.net/lmj623565791/article/details/49300989
    
    提供一个设置图片的入口
    重写onTouchEvent,在里面根据用户移动的手势,去更新显示区域的参数
    每次更新区域参数后,调用invalidate,onDraw里面去regionDecoder.decodeRegion拿到bitmap,去draw


4、常用库使用、实现原理
    glide图片加载
    eventbus发事件消息
        就是在一个单例内部维持着一个map对象存储了一堆的方法;post无非就是根据参数去查找方法,进行反射调用。
    okhttp网络请求


5、流畅度怎么量化测试
    开源测试工具GT


6、anr线上怎么统计
    服务监控(时间间隔)发送错误日志到服务器
    watchdog死锁监控


7、leakcanary的原理,leakcanary 怎么根据dump的文件,分析的引用链。


8、eventbus怎么切换线程
        threadMode
9、页面很卡顿,分析一下原因是什么,然后从哪些方面入手解决
    是否在主线程做耗时操作
    GPU是否过度绘制
    布局层次是否过深
    是否有内存抖动、频繁的GC


10、网络请求的时候遇到的问题?网络请求优化
        减少网络请求次数
        压缩网络请求资源
        网络缓存
    


【算法】


二分查找
快速排序
冒泡排序
用数组实现队列和栈
字符串反转[ok]、二叉树反转[ok]、链表反转
合并排序链表
二叉树的非递归前序遍历
二叉树按层遍历(S形打印二叉树)
求一个树的单行输出[ok]
线程安全的单例模式
堆排序
不用加减乘除实现加法[ok]
求一个view直到子view的深度[ok]
计算出一段英文中的每一单词出现的次数[ok]
求两个排序数组的中位数[ok]
从一个无序数组中找出中位数[ok]
旋转矩阵[ok]
求100以内的质数[ok]
找出单链表最大上升子序列,然后把这些节点删除[ok]


【智力题】
一根绳子烧完要1个小时,我要怎么烧绳子才能确定我过了1个半小时。绳子是不均匀的
N瓶汽水,喝了后,7个空瓶可以再换一瓶,总共可以喝多少瓶


2*8的最快运算是什么?考察点是位运算
ABC三个线程,C线程要等A和B线程的结果,AB并行,问,跟什么数据结构类似
美团:
http://www.kanzhun.com/msh/g711383-z206294/?ka=interview-pos11#co_tab


【算法】
冒泡排序
二分查找算法
反转双向链表
两个链表求和
一百万个数里面取最大的100个数
二叉树前中后序遍历,按层(s型)遍历
计算树的深度
参考:http://blog.csdn.net/gotobar/article/details/48578487
1亿个url存在文件中,里面有重复的url,请问怎么去重
参考:http://blog.csdn.net/u010235716/article/details/78142649
建设1个url,50个字符,每个字符2字节,则一个url是100byte
1亿个url是10G大小,内存放不下。必然要分成多份文件,挨个去去重。
1、单个文件去重,用hashset,将url作为key,循环遍历url,如果hashset里已经有了,就舍去。没有就保存在hashset里,这样得到了10个set
2、然后开始合并set,set1和set2比较,将1中,和2的共同项去掉,再比较1和3,直到1和10。这样使得文件1和后面的所有文件都不重复。
3、重复操作2,完成文件2~10的去重。
4、合并文件1~10
对于二维矩阵,行升序,列升序,找一个数
参考:http://www.voidcn.com/article/p-snfxxirn-km.html
三数之和
参考,java实现:https://www.cnblogs.com/gavanwanggw/p/7253591.html
归并k个长度为n的有序链表
参考:http://shmilyaw-hotmail-com.iteye.com/blog/1776132
两个有序链表,有重复元素,合并出有序无重复元素链表
参考:http://www.tk4479.net/u013159040/article/details/45043349
单链表输出倒数第 k 个元素
参考:http://blog.csdn.net/lvsaixia/article/details/40708811
思路参考:http://blog.csdn.net/sgbfblog/article/details/7877527
字符串匹配
参考:http://blog.csdn.net/DERRANTCM/article/details/47052669
求上述算法的时间复杂度


一共有4个球,其中一个球比较轻,如何测量两次把轻的球找出来
先分成2份,每份2个球,比较。轻的那边说明小球在那边。
再把轻的那边分2份,每份1个,轻的那个就是要找的小球。
手串珠子上色的问题,一个珠子可以有多个颜色,相同的m个珠子不能有重复颜色,问有多少种颜色不满足要求
参考:http://www.cnblogs.com/candy99/p/6851940.html






[头条+快手]


    1、Activity的启动流程
    
    2、App启动流程
            Step 1. 无论是通过Launcher来启动Activity,还是通过Activity内部调用startActivity接口来启动新的Activity,
                    都通过Binder进程间通信进入到ActivityManagerService进程中,并且调用ActivityManagerService.startActivity接口;
            Step 2. ActivityManagerService调用ActivityStack.startActivityMayWait来做准备要启动的Activity的相关信息;
            Step 3. ActivityStack通知ApplicationThread要进行Activity启动调度了,这里的ApplicationThread代表的是
                    调用ActivityManagerService.startActivity接口的进程,对于通过点击应用程序图标的情景来说,这个进程就是Launcher了,
                    而对于通过在Activity内部调用startActivity的情景来说,这个进程就是这个Activity所在的进程了;
            Step 4. ApplicationThread不执行真正的启动操作,它通过调用ActivityManagerService.activityPaused接口进入
                    到ActivityManagerService进程中,看看是否需要创建新的进程来启动Activity;
            Step 5. 对于通过点击应用程序图标来启动Activity的情景来说,ActivityManagerService在这一步中,会调用startProcessLocked
                    来创建一个新的进程,而对于通过在Activity内部调用startActivity来启动新的Activity来说,这一步是不需要执行的,
                    因为新的Activity就在原来的Activity所在的进程中进行启动;
            Step 6. ActivityManagerServic调用ApplicationThread.scheduleLaunchActivity接口,通知相应的进程执行启动Activity的操作;
            Step 7. ApplicationThread把这个启动Activity的操作转发给ActivityThread,ActivityThread通过ClassLoader导入相应的Activity类,
                    然后把它启动起来。
    
    3、Dalvik虚拟机堆分为两部分,jvm没分,为什么,有什么作用?
    
    4、网络请求怎么优化
            减少请求次数
            减少资源大小、压缩
            网络缓存
            
    5、ANR如何进行监控
        开辟子线程监控
        
    6、卡顿如何监控
            利用loop中打印的日志
            利用Choreographer(16ms原则)
        
    7、内部类如何访问外部类私有成员和方法的,外部类如何访问内部类的私有变量和方法?
        1、当内部类调用外部类的私有属性(包括变量和方法)时,其真正的执行是调用了编译器生成的属性的静态方法(即acess0,access1等)
           来获取这些属性值或调用方法。
        2、外部类可以通过内部类的实例获取私有属性x的操作.(在内部类中,会生成一个this$0的变量,这个变量应该就是外部类的实例)
        
    8、一个View,外层为两个ViewGroup,点击View且手指一直滑动到最外层ViewGroup的事件传递是怎样的?view的ontouchevent返回true后会怎样
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值