列举java的集合和继承关系
哪些情况下的对象会被垃圾回收机制处理掉?
(1)超出对象的引用作用域时,这个对象就变成垃圾。
(2)没有超出对象的引用作用域,给这个引用赋值为空,这个引用的对象就变成了垃圾。
(3)创建匿名对象时,匿名对象用完以后即成垃圾
进程和线程的区别?
进程是操作系统中应用程序的抽象,进程和线程都是一个时间段的描述,是CPU工作时间段的描述,不过是颗粒大小不同。
(1) 简而言之,一个程序至少有一个进程,一个进程至少有一个线程
(2) 线程的划分尺度小于进程,使得多线程程序的并发性高
(3) 另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序地运行效率
(4) 线程在执行过程中与进程还是有区别的,每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口,但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制
(5) 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行的部分可以同时执行。单操作系统并没有将多个线程看做是多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的区别
Java 中==和 equals 的区别, equals 和 hashCode 的区别?
==操作符用来比较两个基本类型变量时,比较的是值;用来比较引用类型变量时,比较的是引用的地址
equals方法是基类Object的方法,用于比较两个对象的内容是否相同,Object类中equals方法的默认实现使用的==操作符比较,实际开发过程中,我们会重写equals方法,重新定义比较规则
当涉及到像HashMap等与哈希表结构相关的一些类时,会使用到hashCode方法
默认的hashCode实现一般是内存地址对应的数字,所以不同的对象,hashCode()的返回值是不一样的
equals(object)相同时,hashCode()的返回值也要尽量相同,当equals(object)不相同时,hashCode()的返回没有特别的要求,但是也是尽量不相同以获取好的性能
java 中 int char long 各占多少字节数?
char 2个字节,int 4个字节,long 8个字节
java int 与 integer 的区别
int 是基本数据类型,integer是包装数据类型(引用类型),JDK1.5之后,自动装包/拆包大大方便了基本类型数据和它们包装类地使用。
Integer a = 5; Integer b = 5; a==b 为true,自动做了拆箱转换为int
Integer a = new Integer(5); Integer b = new Integer(5); ; a==b 为false,比较的是a、b对象的内存地址,当然不同。
string stringbuffer stringbuilder 区别
共同点
1、String StringBuffer StringBuilder 都是字符串相关函数
2、StringBuffer StringBuilder都是AbstractStringBuilder的子类
不同点
1、String内容不可变,StringBuffer StringBuilder内容可变
2、String与StringBuffer线程安全,StringBuilder非线程安全
如果程序不是多线程的,那么使用StringBuilder效率高于StringBuffer
Java 多态
静态多态:方法重载
(相同的方法名称,参数不同)
动态多态:方法重写
(子类重写父类方法)
多态发生的条件:
1)要有继承
2)要有重写
3)父类引用指向子类对象
多态的好处:
1)可替换性
2)可扩充性
3)接口性
4)简化性
什么导致线程阻塞
阻塞状态的线程的特点是:该线程放弃CPU的使用,暂停运行,只有等到导致阻塞的原因消除之后才恢复运行。或者是被其他的线程中断,该线程也会退出阻塞状态,同时抛出InterruptedException
1)线程执行了Thread.sleep(int millsecond);方法,当前线程放弃CPU,睡眠一段时间,然后再恢复执行
2)线程执行一段同步代码,但是尚且无法获得相关的同步锁,只能进入阻塞状态,等到获取了同步锁,才能回复执行。
3)线程执行了一个对象的wait()方法,直接进入阻塞状态,等待其他线程执行notify()或者notifyAll()方法。
public class WaitNotifyTest {
Object lock = new Object();
class MyThread extends Thread{
@Override
public void run() {
@Override
public void run() {
while(true) {
synchronized(lock){
try {
System.out.println("waiting for notify");
lock.wait();//阻塞
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("---notified---");
}
}
}
}
}
public static void main(String[] args) {
WaitNotifyTest outClass = new WaitNotifyTest();
outClass.new MyThread().start();
new Thread() {
while(true) {
//每隔2秒,通知打印线程
try {
Thread.sleep(2000);
}catch(InterruptedException e) {
e.printStackTrace();
}
synchronized(outClass.lock) {
outClass.lock.notify();
}
}
}.start();
}
}
4)线程执行某些IO操作,因为等待相关的资源而进入了阻塞状态。比如说监听system.in,但是尚且没有收到键盘的输入,则进入阻塞状态。
抽象类,接口的区别
1)抽象类要被子类继承,接口要被类实现
2)接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现
3)接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
4)抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。
5)抽象方法只能申明,不能实现,接口是设计的结果 ,抽象类是重构的结果
6)接口可继承接口,并可多继承接口,但类只能单根继承。
容器类之间的区别
1)Vector和ArrayList
vector是线程同步的,所以它也是线程安全的,而arraylist是线程异步的,是不安全的。如果不考虑到线程的安全因素,一般用arraylist效率比较高。
如果集合中的元素的数目大于目前集合数组的长度时,vector增长率为目前数组长度的100%,而arraylist增长率为目前数组长度的50%.如过在集合中使用数据量比较大的数据,用vector有一定的优势。
ArrayList 和Vector是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,都允许直接序号索引元素,但是插入数据要设计到数组元素移动等内存操作,所以索引数据快插入数据慢,Vector由于使synchronized方法(线程安全)所以性能上比ArrayList要差
2)arraylist和linkedlist
1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
3.对于新增和删除操作add和remove,LinkedList比较占优势,因为ArrayList要移动数据。这一点要看实际情况的。若只对单条数据插入或删除,ArrayList的速度反而优于LinkedList。但若是批量随机的插入删除数据,LinkedList的速度大大优于ArrayList. 因为ArrayList每插入一条数据,要移动插入点及之后的所有数据。
3)HashMap与TreeMap
1、HashMap通过hashcode对其内容进行快速查找,而TreeMap中所有的元素都保持着某种固定的顺序,如果你需要得到一个有序的结果你就应该使用TreeMap(HashMap中元素的排列顺序是不固定的)。集合框架”提供两种常规的Map实现:HashMap和TreeMap (TreeMap实现SortedMap接口)。
2、在Map 中插入、删除和定位元素,HashMap 是最好的选择。但如果您要按自然顺序或自定义顺序遍历键,那么TreeMap会更好。使用HashMap要求添加的键类明确定义了hashCode()和 equals()的实现。
4)、hashtable与hashmap
1.历史原因:Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现
2.同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的
3.值:只有HashMap可以让你将空值作为一个表的条目的key或value
5)、Set与List
Set中的数据对象没有顺序且不可以重复。
List中的数据对象有顺序且可以重复。
描述一次网络请求的流程
一次完整的HTTP请求所经历的7个步骤
HTTP通信机制是在一次完整的HTTP通信过程中,Web浏览器与Web服务器之间将完成下列7个步骤:
- 建立TCP连接:
在HTTP工作开始之前,Web浏览器首先要通过网络与Web服务器建立连接,该连接是通过TCP来完成的,该协议与IP协议共同构建Internet,即著名的TCP/IP协议族,因此Internet又被称作是TCP/IP网络。HTTP是比TCP更高层次的应用层协议,根据规则,只有低层协议建立之后才能进行更高层协议的连接,因此,首先要建立TCP连接,一般TCP连接的端口号是80。
- Web浏览器向Web服务器发送请求命令:
一旦建立了TCP连接,Web浏览器就会向Web服务器发送请求命令。例如:GET/sample/hello.jsp HTTP/1.1。
- Web浏览器发送请求头信息 :
浏览器发送其请求命令之后,还要以头信息的形式向Web服务器发送一些别的信息,之后浏览器发送了一空白行来通知服务器,它已经结束了该头信息的发送。
- Web服务器应答 :
客户机向服务器发出请求后,服务器会客户机回送应答, HTTP/1.1 200 OK ,应答的第一部分是协议的版本号和应答状态码。
- Web服务器发送应答头信息:
正如客户端会随同请求发送关于自身的信息一样,服务器也会随同应答向用户发送关于它自己的数据及被请求的文档。
- Web服务器向浏览器发送数据:
Web服务器向浏览器发送头信息后,它会发送一个空白行来表示头信息的发送到此为结束,接着,它就以Content-Type应答头信息所描述的格式发送用户所请求的实际数据。
- Web服务器关闭TCP连接 :
一般情况下,一旦Web服务器向浏览器发送了请求数据,它就要关闭TCP连接,然后如果浏览器或者服务器在其头信息加入了这行代码:Connection:keep-alive;TCP连接在发送后将仍然保持打开状态,于是,浏览器可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络带宽。
Handler、 Thread 和 HandlerThread 的差别
Handler会关联一个单独的线程和消息队列,Handler默认关联主线程,如果要在其他线程执行,可以使用HandlerThread。
HandlerThread继承于Thread,所以它本质就是个Thread。与普通Thread的差别就在于,主要的作用是建立了一个线程,并且创立了消息队列,有来自己的looper,可以让我们在自己的
程中分发和处理消息。
TCP 的 3 次握手和四次挥手
三次握手:
TCP是面向连接的,无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。在TCP/IP协议中,TCP协议提供可靠的连接服务,连接是通过三次握手进行初始化的。三次握手的目的是同步连接双方的序列号和确认号并交换 TCP窗口大小信息。
第一次握手:建立连接。客户端发送连接请求报文段,将SYN位置为1,Sequence Number为x;然后,客户端进入SYN_SEND状态,等待服务器的确认;
第二次握手:服务器收到SYN报文段。服务器收到客户端的SYN报文段,需要对这个SYN报文段进行确认,设置Acknowledgment Number为x+1(Sequence Number+1);同时,自己自己还要发送SYN请求信息,将SYN位置为1,Sequence Number为y;服务器端将上述所有信息放到一个报文段(即SYN+ACK报文段)中,一并发送给客户端,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK报文段。然后将Acknowledgment Number设置为y+1,向服务器
发送ACK报文段,这个报文段发送完毕以后,客户端和服务器端都进入ESTABLISHED状态,完成TCP三次握手。
简单说就是客户端发送SYN报文段给服务端,服务端返回SYN+ACK给客户端,客户段又发送ACK给服务端,建立连接
四次分手:
当客户端和服务器通过三次握手建立了TCP连接以后,当数据传送完毕,肯定是要断开TCP连接的啊。那对于TCP的断开连接,这里就有了神秘的“四次分手”。
第一次分手:主机1(可以使客户端,也可以是服务器端),设置Sequence Number和Acknowledgment Number,向主机2发送一个FIN报文段;此时,主机1进入FIN_WAIT_1状态;这表示主机1没有数据要发送给主机2了;
第二次分手:主机2收到了主机1发送的FIN报文段,向主机1回一个ACK报文段,Acknowledgment Number为Sequence Number加1;主机1进入FIN_WAIT_2状态;主机2告诉主机1,我“同意”你的关闭请求;
第三次分手:主机2向主机1发送FIN报文段,请求关闭连接,同时主机2进入LAST_ACK状态;
第四次分手:主机1收到主机2发送的FIN报文段,向主机2发送ACK报文段,然后主机1进入TIME_WAIT状态;主机2收到主机1的ACK报文段以后,就关闭连接;此时,主机1等待2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,主机1也可以关闭连接了。
TCP 与 UDP 的区别
1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接
2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
3、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
4、TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的UDP没有拥塞控制,因此网络出现拥塞不会使源主机发送速率降低(对实时应用很有用,如IP电话,实时视频会议)
5、TCP首部开销20字节;UDP的首部开销小,只有8个字节
6、TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道
数据库的操作类型有哪些,如何导入外部数据库?
读懂题目。如果碰到问题比较模糊的时候可以适当问问面试官。
配合面试官来面试:面试是一个相互了解的过程,要充分利用面试的题目和时间把自己的能力和技术展现出来,面试官能够看到你的真实技术。
1)使用数据库的方式有哪些?
(1)openOrCreateDatabase(String path);
(2)继承SqliteOpenHelper类对数据库及其版本进行管理(onCreate,onUpgrade)
当在程序当中调用这个类的方法getWritableDatabase()或者getReadableDatabase();的时候才会打开数据库。如果当时没有数据库文件的时候,系统就会自动生成一个数据库。
2)操作的类型:增删改查CRUD
直接操作SQL语句:SQliteDatabase.execSQL(sql);
面向对象的操作方式:SQLiteDatabase.insert(table, nullColumnHack, ContentValues);
如何导入外部数据库?
一般外部数据库文件可能放在SD卡或者res/raw或者assets目录下面。
写一个DBManager的类来管理,数据库文件搬家,先把数据库文件复制到”/data/data/包名/databases/”目录下面,然后通过db.openOrCreateDatabase(db文件),打开数据库使用。
我上一个项目就是这么做的,由于app上架之前就有一些初始数据需要内置,也会碰到数据的升级等问题,我是这么做的…… 同时我碰到最有意思的问题就是关于数据库并发操作的问题,比如:多线程操作数据库的时候,我采取的是封装使用互斥锁来解决……
是否使用过本地广播,和全局广播有什么差别?
引入本地广播的机制是为了解决安全性的问题:
1)正在发送的广播不会脱离应用程序,比用担心app的数据泄露;
2)其他的程序无法发送到我的应用程序内部,不担心安全漏洞。(比如:如何做一个杀不死的服务—监听火的app 比如微信、友盟、极光的广播,来启动自己。)
3)发送本地广播比发送全局的广播高效。(全局广播要维护的广播集合表 效率更低。全局广播,意味着可以跨进程,就需要底层的支持。)
本地广播不能用静态注册。—-静态注册:可以做到程序停止后还能监听。
使用:
(1)注册
LocalBroadcastManager.getInstance(this).registerReceiver(new XXXBroadCastReceiver(), new IntentFilter(action));
(2)取消注册:
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver)
发送ACK报文段,这个报文段发送完毕以后,客户端和服务器端都进入ESTABLISHED状态,完成TCP三次握手。