常见Java面试题(一)

面向对象的特征有哪些

面向对象有四大基本特征:封装、抽象、继承、多态

抽象

抽象就是找出一些事物的相似和共性之处,然后将这些事物归为一个类。 就是把现实生活中的对象,抽象为类。

封装

封装就是将对象封装成一个高度自治和相对封闭的个体,对象属性由这个对象自己的方法来读取和改变。
如:一个人,他的姓名等属性,要有自己提供的get和set的方法来操作。private naame setName getNme

继承

在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并可以加入若干新的内容,或修改原来的方法使之更适合特殊的需要,这就是继承。

多态

多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。接口的多种不同的实现方式就是多态。

有了基本数据类型,为什么还需要包装类型

Java是一个面相对象的编程语言,而基本数据类型并不具有对象的性质,为了让基本类型也具有对象的特征,就出现了包装类型,它相当于将基本类型“包装起来”,使得它具有了对象的性质,并且为其添加了属性和方法,丰富了基本类型的操作。

“==”和equals有什么区别

首先数据的表示有基本类型和引用类型。
== 基本类型比较值是否相同
   引用类型比较的是地址是否相同
equals()
  只能比较引用类型,默认情况下比较的是地址值是否相同。
但在一些类中重写了这个方法,如包装类,String,Date等,equals()比较的是两个变量的值。

String、StringBuilder、StringBuffer的区别

1.String是内容不可变的字符串。String底层使用了一个不可变的字符数组(final char[])
而StringBuillder StringBuffer,是内容可以改变的字符串。StringBuillder StringBuffer底层使用的可变的字符数组(没有使用final来修饰)
2.最经典就是拼接字符串。
String进行拼接.String str = "a" + "b";
StringBuilder或者StringBuffer
StringBuilder sb = new StringBuilder(); sb.apend("a").apend("b")
拼接字符串不能使用String进行拼接,要使用StringBuilder或者StringBuffer
3.StringBuilder是线程不安全的,效率较高.而StringBuffer是线程安全的,效率较低。

Java中的集合

Java中的集合分为value,key–vale(Conllection Map)两种。
存储值的有List和Set
List是有序的,可以重复的。
Set是无序的,不可以重复的。根据equals和hashcode判断,也就是如果一个对象要存储在Set中,必须重写equals和hashCode方法。
存储key-value的有map.

ArrayList和LinkedList的区别

ArrayList底层使用时数组。LinkedList使用的是链表
数组查询具有查询特定元素比较快。而插入、删除和修改比较慢(数组在内存中是一块连续的内存,如果插入或删除是需要移动内存)。 链表不要求内存是连续的,在当前元素中存放下一个或上一个元素的地址。查询时需要从头部开始,一个一个的找。所以查询效率低。插入时不需要移动内存,只需改变引用指向即可。所以插入或者删除的效率高。
ArrayList使用在查询比较多,但是插入和删除比较少的情况,而LinkedList使用在查询比较少而插入和删除比较多的情况。

HashMap、HashTable、ConcurrentHashMap的区别

HashMap的实现原理
HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体. HashMap 在底层将 key-value 当成一个整体进行处理,这个整体就是一个 Entry 对象。HashMap 底层采用一个 Entry[] 数组来保存所有的 key-value 对,当需要存储一个 Entry 对象时,会根据 hash 算法来决定其在数组中的存储位置,在根据 equals 方法决定其在该数组位置上的链表中的存储位置;当需要取出一个Entry 时,也会根据 hash 算法找到其在数组中的存储位置,再根据 equals 方法从该位置上的链表中取出该Entry。
相同点:HashMap和HasheTalbe都可以使用来存储key–value的数据。
区别:
1、HashMap是可以把null作为key或者value的,而HashTable是不可以的。
2、HashMap是线程不安全的,效率较高。而HashTalbe是线程安全的,效率较低。
ConcurrentHashMap通过把整个Map分为N个Segment(类似HashTable),可以提供相同的线程安全,但是效率提升。

哈希冲突怎么解决

开放定址法
这种方法也称再散列法,其基本思想是:当关键字key的哈希地址p=H(key)出现冲突时,以p为基础,产生另一个哈希地址p1,如果p1仍然冲突,再以p为基础,产生另一个哈希地址p2,…,直到找出一个不冲突的哈希地址pi ,将相应元素存入其中。

Java线程的6种状态

  1. 初始(NEW):新创建了一个线程对象,但还没有调用start()方法。
  2. 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。
    线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)。
  3. 阻塞(BLOCKED):表示线程阻塞于锁。
  4. 等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。
  5. 超时等待(TIMED_WAITING):该状态不同于WAITING,它可以在指定的时间后自行返回。
  6. 终止(TERMINATED):表示该线程已经执行完毕。

线程池参数详解

corePoolSize:核心线程池数量
在线程数少于核心数量时,有新任务进来就新建一个线程,即使有的线程没事干
等超出核心数量后,就不会新建线程了,空闲的线程就得去任务队列里取任务执行了
maximumPoolSize:最大线程数量
包括核心线程池数量 + 核心以外的数量
如果任务队列满了,并且池中线程数小于最大线程数,会再创建新的线程执行任务
keepAliveTime:线程超时时间。
如果给线程池设置 allowCoreThreadTimeOut(true),则核心线程在空闲时头上也会响起死亡的倒计时
如果任务是多而容易执行的,可以调大这个参数,那样线程就可以在存活的时间里有更大可能接受新任务
workQueue:任务队列
不同的任务类型有不同的选择,下一小节介绍
threadFactory:线程工厂。线程池利用该工厂创建线程。
可以给线程起个好听的名字,设置个优先级啥的
handler:线程任务拒绝策略
CallerRunsPolicy:只要线程池没关闭,就直接用调用者所在线程来运行任务
AbortPolicy:直接抛出 RejectedExecutionException 异常
DiscardPolicy:悄悄把任务放生,不做了
DiscardOldestPolicy:把队列里待最久的那个任务扔了,然后再调用 execute() 试试看能行不
我们也可以实现自己的 RejectedExecutionHandler 接口自定义策略,比如如记录日志什么的

线程的几种实现方式

1、通过继承Thread(斯ruai德)类实现一个线程
2、通过实现Runnable接口实现一个线程
继承扩展性不强,java总只支持单继承,如果一个类继承Thread就不能继承其他的类了。

线程池的作用

1、限定线程的个数,不会导致由于线程过多导致系统运行缓慢或崩溃
2、线程池不需要每次都去创建或销毁,节约了资源、
3、线程池不需要每次都去创建,响应时间更快。

常用的设计模式有哪些

单例(懒汉模式、饿汉模式)
1、构造方法私有化,除了自己类中能创建外其他地方都不能创建
2、在自己的类中创建一个单实例(饿汉模式是类加载就创建单实例,而懒汉模式是第一次被使用的时候才创建)
3、提供一个方法获取该实例对象(创建时需要进行方法同步)
工厂模式:Spring IOC就是使用了工厂模式.对象的创建交给一个工厂去创建。
代理模式:Spring AOP就是使用的动态代理。

Synchronized修饰静态方法和非静态方法有什么区别

修饰非静态方法,实际上是对调用该方法的对象加锁,俗称“对象锁”。
修饰静态方法,实际上是对该类对象加锁,俗称“类锁”。

Synchronized和ReentrantLock的区别

两者的共同点:
可重入,同一线程可以多次获得同一个锁
两者的不同点:
ReentrantLock手动开启、释放锁,synchronized隐式开启释放锁
ReentrantLock可响应中断、可轮回,synchronized是不可以响应中断的,为处理锁的不可用性提供了更高的灵活性
ReentrantLock 依赖于 API,而synchronized依赖于JVM
ReentrantLock可以实现公平锁
ReentrantLock通过Condition可以绑定多个条件

Java多线程公平锁与非公平锁

公平锁:加锁前检查是否有排队等待的线程,优先排队等待的线程,先来先得
非公平锁:加锁时不考虑排队等待问题,直接尝试获取锁,获取不到自动到队尾等待

Java可重入锁与不可重入锁

所谓重入锁,指的是以线程为单位,当一个线程获取对象锁之后,这个线程可以再次获取本对象上的锁

乐观锁与悲观锁

悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁
乐观锁:总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据。

数据库事务隔离级别

隔离级别 脏读 不可重复读 幻读
读未提交 可能 可能 可能
读已提交 不可能 可能 可能
可重复读 不可能 不可能 可能
可串行化 不可能 不可能 不可能

读未提交:允许脏读,也就是可能读取到其他会话中未提交事务修改的数据
读已提交:只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)
可重复读:可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读
串行读:完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞

1.脏读: 脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。
2.不可重复读:是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读
3.幻读:第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。

MySQL索引类型

B+Tree、哈希索引、R-Tree、全文索引

B+Tree相对于B-Tree有几点不同

1.非叶子节点是叶子节点的索引
2.要存储的数据都存放在叶子节点中
3.叶子节点之间都有一个链指针,不需要遍历整棵树就可以得到所存储的全部数据

MySQL执行引擎有哪些

InnoDB、MyIsam

MyISAM 和 INNODB的区别

  1. 事务安全 myisam不支持事务而innodb支持
  2. 查询和添加速度 myisam不用支持事务就不用考虑同步锁,查找和添加和添加的速度快
  3. 支持全文索引 myisam支持innodb不支持
  4. 锁机制 myisam支持表锁而innodb支持行锁(事务)
  5. 外键MyISAM不支持外键,INNODB支持外键. (通常不设置外键,通常是在程序中保证数据的一致)

缓存穿透

缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时被动写的,并且出于容错考虑,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。在流量大时,可能DB就挂掉了,要是有人利用不存在的key频繁攻击我们的应用,这就是漏洞。

排序算法有那些

选择排序、插入排序、冒泡排序、希尔排序、归并排序、快速排序、堆排序、基数排序、桶排序

HTTP状态码

200 - 请求成功
301 - 资源(网页等)被永久转移到其它URL
302 - 重定向
404 - 请求的资源(网页等)不存在
500 - 内部服务器错误

Session的两种实现方式

1.通过cookie
创建Session的时候,服务器将生成一个唯一的sessionid然后用它生成一个关闭浏览器就会失效的cookie。
2.url重写
通过cookie可以很好地实现session,但是如果客户端由于某些原因(比如出于安全考虑)而禁用cookie,在这种情况之下,为了使session能够继续生效,可以采用url重写。

如何解决负载均衡之后的session共享问题

1.不使用session,换作cookie
2.数据库记录下session信息
4.对session文件进行同步。

Mybatis一级缓存、二级缓存

一级缓存是SqlSession级别的缓存,放在session里面,在对象中有一个数据结构(HashMap)用于存储缓存数据。
二级缓存是mapper级别的缓存,放在它的命名空间里

欢迎关注我的其它发布渠道