Java面试学习总结(1)

来源:互联网 发布:特价机票全额退款 知乎 编辑:程序博客网 时间:2024/05/22 11:43

1.  Java中Object类提供的方法

equals(),hashCode(),toString(),wait(),wait(longparamLong),

wait(longparamLong, int paramInt)【阻塞可被中断】,

notify(),notifyAll(),getClass(),clone(),

finalize():当GC确定不存在对该对象的更多引用时,由对象的GC调用此方法。

2.  Java中IO包下InputStream所运用的设计模式

Java语言采用流【数据的有序排列】的机制来实现输入/输出,InputStream是输入流,其运用的设计模式有装饰器模式和适配器模式,详情可参考:https://my.oschina.net/gao0516/blog/136103。

3.  ArrayList跟LinkedList的区别

LinkedList的插入和删除时比ArrayList更高效,但是ArrayList在随机访问方面比LinkedList更高效;

LinkedList的添加可以使其用作栈,队列或双端队列的方法;

ArrayList是基于动态数组的数据结构,LinkedList是基于链表的数据结构。

4.  Session和Cookie的区别

Session信息保存在服务器上,对客户端不可见,用来跟踪用户的状态,保存上下文信息的机制【由Http是无状态的协议所致】;Cookie信息保存在客户端,对服务器可见,用来记录用户的信息,是Session实现的一种方式;

在访问量增强的情形下,Session会消耗服务器的性能,在客户端完全禁止Cookie的情形下会导致Session失效【例如URL重写由Cookie实现,SessionId保存在Cookie中,JSESSIONID即是浏览器内存中的“输出Session Cookie”】。

Session中保存的是对象,Cookie中保存的是字符串且大小和数量有限【通常是单个不超过4K且不超过20个】;

Session不能区分路径,同一个用户在访问一个网站期间,所有的Session在任何一个地方都可以访问到;而Cookie中如果设置了路径参数,那么同一个网站中不同路径下的Cookie互相是访问不到的。

5.  快速排序的实现原理

快速排序的平均时间复杂度为O(nlogn),采用的是分治的递归算法,详情可参考:

http://blog.csdn.net/happy_wu/article/details/51841244。

6.  Java中类实现Serializable接口的作用

Java的对象序列化将那些实现Serializable接口的对象转换成一个字节序列,并能够通过反序列化将这个字节序列完全恢复为原来的对象;将序列化的对象写入磁盘,然后再反序列化时恢复该对象,就能够实现持久性的效果。

对象序列化是为了支持两种主要特性:RMI使存活于其它计算机上的对象使用起来就像存活于本机上一样;JavaBean在设计阶段对它的状态信息进行配置,这种状态信息必需保存下来,并在程序启动时进行后期恢复,这种具体工作就是由对象序列化完成的。

7.  HashMap排序的实现

https://github.com/chunericli/common-wise-utils/tree/master/wise-utils-commonutils/src/main/java/com/wise/utils/map。

8. 多线程的概述

http://blog.jobbole.com/76308/,

http://blog.csdn.net/lichunericli/article/details/78657708。

9. TCP/IP的三次握手

建立连接(客户端和服务端,一一对应):

1客户端发送SYN段给服务器,指明客户打算连接的服务器的端口以及初始号,这个SYN段为报文段1。

2服务器发回包含服务器的初始序号的SYN报文段(报文段2)作为应答,同时将确认序号设置为客户的ISN加1以对客户的SYN报文段进行确认。

3客户必须将确认序号设置为服务器的ISN加1以对服务器的SYN报文段进行确认(报文段3)。

以上三个报文段完成连接的建立,这个过程称为三次握手。

TCP是面向连接,可靠的字节流服务【服务端和客户端在交换数据的时候是可以进行独立传输的全双工服务】;每个TCP段都包含发送端和接收端的端口号。

10.ArrayList底层实现

线程不是线程同步的;ArrayList的底层是可变数组的实现;允许null元素的存储;默认容量大小为10;每次扩容都是按照当前数组长度的1.5倍进行内存分大小分配;每次扩容都会进行数组数据的拷贝到新数组。

Note:Arraylist和HashMap在容量足够时,使用add方法添加数据时会比较快,如果在扩容时添加数据速度则会比较慢;在中间位置插入或者删除数据时会因为数据位置的变动,从而导致效率低;但是无论任何时候,其内存都是连续的,随机索引访问效率很高。

11.Servlet容器的生命周期

Servlet容器的生命周期定义包括:类加载,初始化,处理请求和实例销毁。Servlet被服务器实例化后,容器运行其init方法,请求到达时运行其service方法,service方法自动派遣运行与请求对应的doXXX方法(doPost和doGet),当服务器决定把实例销毁的时候调用其destroy方法。

12.List去重

【仅限于数据集有限的情形】集合排序后去重;使用set处理。

13.Volatile如何保证内存可见性

【深入理解Java虚拟机】观察加入volatile关键字和没有加入volatile关键字时所生成的汇编代码发现,加入volatile关键字时,会多出一个lock前缀指令。

lock前缀指令实际上相当于一个内存屏障(也成内存栅栏),内存屏障会提供3个功能:

1)它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成;

2)它会强制将对缓存的修改操作立即写入主存;

3)如果是写操作,它会导致其它CPU中对应的缓存行无效。

14.Volatile不能保证原子性

15.TCP连接安全可靠的保证

1.应用数据被分割成TCP认为最适合发送的数据块【不同于UDP】,应用程序产生的数据报长度将保持不变,由TCP传递给IP的信息单位称为报文段或段(segment);

2.当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重新发这个报文段(自适应的超时重传);

3.当TCP收到来自TCP连接另一端的数据,它将发送一个确认;

4.TCP将保持它首部和数据的校验和,端到端的检验和,目的是检测数据在传输过程中的任何变化,如何收到段的检验和有差错,TCP将丢弃这个报文段和不确认收到此报文段;

5.既然TCP报文段作为IP数据报来传输,而IP数据报的到达可能会失序,因此TCP报文段的到达也可能会失序。如果必要TCP将对收到的数据进行重新排序,将收到的数据以正确的顺序给应用层;

6.既然IP数据报会发生重复,TCP的接收端必须丢弃重复数据;

7.TCP能提供流量控制,TCP中的双方都有固定大小的缓冲空间,TCP的接收端只允许接收缓冲区所能接纳的数据,这将防止较快主机致使较慢主机的缓冲区溢出。

16.数据库中默认存在的表

Time_zone_name,servers,Innodb_table,db,User,innodb_index_stats,proc

17.Java的引用类型

强引用:类似于Object obj = new Object()这类的引用,只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象。

软引用:在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围之中进行第二次回收,如果这次回收还没有足够的内存,才会抛出内存溢出异常。

弱引用:对象只能生存到下一次垃圾收集发生之前,当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。

虚引用:也称为幽灵引用或者幻影引用,一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例,为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。

18.抽象类和接口的区别

1.抽象类里可以有构造方法,而接口内不能有构造方法。

2.抽象类中可以有普通成员变量,而接口中不能有普通成员变量。

3.抽象类中可以包含非抽象的普通方法,而接口中所有的方法必须是抽象的,不能有非抽象的普通方法。

4.抽象类中的抽象方法的访问类型可以是public,protected和默认类型,但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。

5.抽象类中可以包含静态方法,接口内不能包含静态方法。

6.抽象类和接口都可包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static类型,并且默认为public static类型。

7.类可以实现多个接口,但只能继承一个抽象类。

19.关系型和非关系型数据库区别
优点:
1)成本:nosql数据库开源,简单易部署,相比关系型数据库价格便宜【Oracle】;
2)查询速度:nosql数据库将数据存储于缓存之中,关系型数据库将数据存储在硬盘中;
3)存储数据的格式:nosql的存储格式是key,value形式、文档形式、图片形式等等,可以存储基础类型,对象或者集合等各种格式,而数据库则只支持基础类型;
4)扩展性:关系型数据库有类似join这样的多表查询机制的限制导致扩展很艰难;
缺点:
1)维护的工具和资料有限;
2)不提供SQL的支持;
3)不提供关系型数据库对事物的处理。

20.索引的分类

MySQL的索引包括普通索引、唯一性索引、全文索引、单列索引、多列索引和空间索引等。

1.普通索引

在创建普通索引时,不附加任何限制条件,这类索引可以创建在任何数据类型中,其值是否唯一和非空由字段本身的完整性约束条件决定。

2.唯一性索引

使用UNIQUE参数可以设置索引为唯一性索引,主键就是一种特殊唯一性索引。

3.全文索引

使用FULLTEXT参数可以设置索引为全文索引,全文索引只能创建在CHAR、VARCHAR或TEXT类型的字段上。默认情况下全文索引的搜索执行方式不区分大小写,但索引的列使用二进制排序后,可以执行区分大小写的全文索引。

4.单列索引

在表中的单个字段上创建索引,单列索引只根据该字段进行索引,单列索引可以是普通索引,也可以是唯一性索引,还可以是全文索引,只要保证该索引只对应一个字段即可。

5.多列索引

多列索引是在表的多个字段上创建一个索引,在查询条件中使用了这些字段中第一个字段时,索引才会被使用。

6.空间索引

使用SPATIAL参数可以设置索引为空间索引,空间索引只能建立在空间数据类型上,MySQL中的空间数据类型包括 GEOMETRY和POINT、LINESTRING和POLYGON等,目前只有MyISAM存储引擎支持空间检索,而且索引的字段不能为空值。

索引是单独的、物理的数据库结构,是表中一列或若干列值的集合和对应的指向表中物理标识这些值的数据的逻辑指针清单,详情可以参考:

http://www.3lian.com/edu/2013/07-24/83766.html。

21.排序算法与空间复杂度

    排序法

最差时间分析

平均时间复杂度

稳定度

空间复杂度

冒泡排序

O(n2)

O(n2)

稳定

O(1)

快速排序

O(n2)

O(n*log2n)

不稳定

O(log2n)~O(n)

选择排序

O(n2)

O(n2)

稳定

O(1)

二叉树排序

O(n2)

O(n*log2n)

不一顶

O(n)

插入排序

O(n2)

O(n2)

稳定

O(1)

堆排序

O(n*log2n)

O(n*log2n)

不稳定

O(1)

希尔排序

O

O

不稳定

O(1)

22.类加载器

http://www.ibm.com/developerworks/cn/java/j-lo-classloader/。

23.HashMap,HashTable,ConcurrentHashMap的区别

HashMap继承自AbstractMap,HashTable继承自Dictionary,它们都实现了Map<K, V>, Cloneable,Serializable接口。HashMap允许null值和null键的存在,HashTable不允许null值和null键的存在;HashMap通过包装可实现线程同步,HashTable本身采用synchronized来实现线程同步,所有的操作会锁住整个对象,性能较差。

HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的,ConcurrentModificationException异常的抛出与否,根据JVM的差异会存在不同的表现方式,这也是Enumeration和Iterator的区别。

HashMap和HashTable底层实现类似,都是基于Entry数组的实现,其扩容机制【index计算方法和扩容大小2n:2n+1】和默认大小【16:11】存在差异,但是其默认的负载因子都是0.75【实践和空间代价之间的某种平衡】。

HashMap不能保证随着时间的推移Map中的元素次序是不变的【持保留意见】。

ConcurrentHashMap是线程安全的Map且不涉及同步锁,其内部使用Segment数组,每个Segment类似于HashTable,在写线程或者部分特殊的读线程中锁住的是某个Segment对象,其它的线程能够并发执行其它的Segment对象。

24.sleep和wait的区别

sleep是线程类Thread类的方法,阻塞过程中释放资源但是不释放锁;wait是Object类的方法,对象调用wait会导致本线程释放对象锁并进入等待池等待,只有当其它线程调用notify/notifyAll方法时,线程结束wait状态。都能被中断处理。

25.进程间的通信

管道( pipe ):半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用,进程的亲缘关系通常是指父子进程关系;

有名管道(named pipe):半双工的通信方式,但是它允许无亲缘关系进程间的通信;

信号量(semophore):可以用来控制多个进程对共享资源的访问的计数器;

消息队列(message queue):消息队列克服了信号传递信息少,管道只能承载无格式字节流以及缓冲区大小受限等缺点;

信号量(signal):信号是比较复杂的通信方式,用于通知接收进程某个事件已经发生;

共享内存(shared memory):共享内存是最快的IPC方式;

套接字(socket):Socket可用于不同的进程通信。

26.对多态的理解

同一操作作用于不同的对象有着不同的解释,产生不同的执行结果,在运行时可以通过指向基类的指针来调用实现派生类中的方法,多态是消除类型间的耦合关系。

编译时的多态性:通过重载来实现的,对于非虚的成员来说,系统在编译时,根据传递的参数、返回的类型等信息决定实现何种操作。

运行时的多态性:直到系统运行时,才根据实际情况决定实现何种操作。

编译时的多态性为提供了运行速度快的特点,而运行时的多态性则带来了高度灵活和抽象的特点。

27.TCP断开连接过程

终止一个连接需要4次握手,这是由TCP的半关闭造成的。TCP连接是全双工(即数据在两个方向上能同时传递),因此每个方向必须单独进行关闭。

首先进行关闭的一方(即发送第一个FIN)将执行主动关闭,而另一方(收到这个FIN)执行被动关闭。TCP客户端发送一个FIN,用来关闭从客户到服务器的数据传送。当服务器收到这个FIN,它发挥一个ACK,确认序号为收到的序号加1(报文段5)和SYN一样,一个FIN将占用一个序号。同时TCP服务器还向应用程序(即丢弃服务器)传送一个文件结束符。接着这个服务器程序关闭它的连接,导致它的TCP端发送一个FIN(报文段6),客户必须发回一个确认,并将确认序号设置为收到序号加1(报文段7)。

28.海量数据的处理

http://blog.csdn.net/v_JULY_v/article/details/6279498。

29.死锁的原理和必要条件

产生死锁的原因主要是:
系统资源不足;进程运行推进的顺序不合适;资源分配不当等。
产生死锁的四个必要条件:
互斥条件:一个资源每次只能被一个进程使用;
请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放;
不剥夺条件:进程已获得的资源,在末使用完之前不能强行剥夺;
循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

死锁的避免:

  • 如果一个进程的当前请求的资源会导致死锁,系统拒绝启动该进程;
  • 如果一个资源的分配会导致下一步的死锁,系统就拒绝本次的分配。

30.数据库中的锁

共享锁:多个事务可封锁一个共享页,任何事务都不能修改该页,通常是该页被读取完毕,S锁立即被释放;

排它锁:仅允许一个事务封锁此页,其它任何事务必须等到X锁被释放才能对该页进行访问,X锁一直到事务结束才能被释放;

更新锁:用来预定要对此页施加X锁,它允许其它事务读,但不允许再施加U锁或X锁,当被读取的页将要被更新时,则升级为X锁,U锁一直到事务结束时才能被释放;

Mysql行级锁,表级锁,页级锁。

表级锁:引擎MyISAM,理解为锁住整个表,可以同时读,写不行
行级锁:引擎INNODB,单独的一行记录加锁