Android面试-java基础

面向对象:封装,继承,多态
封装:把客观事物封装成抽象类,暴露出来一些方法给用户,保护内部数据
继承:某个对象获取另一个对象的所有属性和方法
多态:类实例的相同方法有不同的表现形式

类加载过程:
BootStrap,Extension,App
Android:Boot即系统的,PathDex已有的即apk的,Dex
1.通过classLoader将class加载到虚拟机,生成Class对象
2.验证,验证文件格式等符合虚拟机的要求
3.准备,对基本类型,常量等赋值
4.解析,符号引用替换为直接引用
5.初始化
6.使用
7.卸载
类加载触发时机:
1.new;2.访问类的静态变量和静态方法;3.反射使用;4.初始化类,先初始化父类;5.main()方法初始化

1.final、finally与finalize的区别
final修饰类(不能被继承)
修饰方法(不能被重写)
修饰变量(不能被修改)
finally
用在try/catch中
一定会被执行,除非调用System.exit(0)
finally会撤销之前的return,如果他有return
如果没有,他是不会改变try里面的return的值(当然对象里面的值会改变)
finalize
finalize只调用一次,可能调用完之后不需要回收对象,但是后期需要回收的时候就不会调用他了,所以最好不要使用
2.String、StringBuffer、StringBuilder
String每次复制会创建一个新对象,即“+”时会创建一个新对象,但是线程安全,内部是final char[],不可修改的
StringBuffer,线程不安全,通过append添加数据,
StringBuilder用于多线程,加了同步锁,所以效率稍低
string 的 “+” 操作就是根据 StringBuilder类及其 append 方法实现的
但是不能再对象上做“+”操作,否则生成的是一个新对象
3.ArrayLists和LinkedList的区别
一个是数组和链表,数组扩容的时候会扩展为原来的1.5倍,会浪费空间
4.HashMap、Hashtable、ConcurrentHashMap的原理与区别
HashTable和hashmap都是通过数组加链表实现的,java8以后,更新了,如果数据过大,则把链表换成红黑树
hashtable,key和value均不能为null
hashmap均可以
ConcurrentHashMap内部采用分段的数组实现,每段数组加了一把锁
LinkedHashMap增加了一个双向链表来记录顺序
SparseArray和ArrayMap
避免了key装箱的过程,不依赖一个额外的Entry对象,两个数组存的
ArrayMap两个数组,一个存的是key的hash,一个存的是key/value对象
LruCache维护了一个linkedhashmap,accessOrder保证访问顺序,最近最少使用
put方法时,先put,然后把之前的移除掉,然后计算trimToSize的大小,超出缓存确定的大小时,把之前的队首元素删除


https的原理:
客户端请求服务端,服务端发送公钥给客户端,客户端检查公钥,正确则生成对称加密的秘钥,用公钥加密发送给服务端,服务端解密
获取秘钥,然后通过这个来通信

TCP/UDP
tcp面向连接可靠的,点对点的,效率稍低的,用于Http,ftp
udp非面向连接的,多对多,效率高,用于视频流
三次握手:
1.客户端发送syn请求
2.服务端接收到后,发送syn和ack确认
3.客户端收到后,发送ack确认
四次挥手:
1.客户端发送fin关闭
2.服务端发送ack,进入等待
3.服务端发送fin
4.客户端发送ack

实现ServerSocket和Socket

打开链接到Socket的输入输出流

进行读写操作,关闭流和socket
socket:accept阻塞
http:请求行Post,相对url,http版本
请求头:主机名,cookie等
空行:隔离
请求体:请求参数
响应行:响应码,2xx处理成功,4xx主要在客户端,5xx主要在服务端
响应头:时间等信息
响应体,后台返回的json数据

token比cookie更先进,是验证用户身份
线程池:ThreadPoolExecutor(核心线程数,最大线程数,闲置时长,时间,阻塞队列,线程工厂,拒绝策略)
工作过程:先调用核心线程,然后把其他的加入队列中,满了加入非核心线程中,否则就拒绝
四种线程池:
1.newSingleThreadExecutor只有一个核心线程,有无界的缓存队列
2.ScheduledThreadPool定长线程池,优先级缓存队列
3.newFixedThreadPool固定的核心线程数
4.newCachedThreadPool,0个核心线程,无缓存队列
线程间通信通过notify,wait,synchronized
synchronized/volidate/Lock(保持内存可见性和禁止指令重排序写和读的时候加屏障)
unlock会造成死锁,lock获取锁,乐观锁,不会被阻塞,会不断的去请求
线程:
1.Thread和Runnable
2.start不代表开始,只是加入了就绪队列,都实现了run方法
3.sleep(long millis)阻塞线程不会释放锁,wait会释放锁,notify是唤醒线程
创建,就绪,运行,阻塞,死亡
停止任务:stop会停止线程,会停止所有,可能导致一些清理工作没做
suspend()和resume()必须要成对出现,否则非常容易发生死锁
interrupt中断线程,保证run方法有终点

垃圾回收机制:
不需要某些对象时,释放其内存
怎么查找不需要的对象:
1.引用计数法
被引用一次+1,引用失效-1
两个相互引用的会永远gc不了,就会造成内存泄漏
2.可达性算法
GCRoots开始搜索
栈帧局部变量表所引用的对象
本地方法栈所引用的对象
静态变量和常量所引用的对象

java内存模型:

主内存:

堆,方法区,线程共享

工作内存:

方法栈,本地方法栈,程序计数器(每个线程都有)

抽象类和接口都不能被实例化
抽象类可以有普通方法(包括构造函数),抽象方法必须被重写
接口可以多实现,类只能单继承
抽象类经常用于表达是不是某一类东西,而接口只是用来表达方法的实现
抽象类里面可以有成员变量,接口里面只能有静态常量

 

 

你可能感兴趣的:(Android,Studio)