java基础
重载与重写
String 和StringBuffer ,StringBuilder的区别
接口和抽象类的区别,什么时候用接口,什么时候用抽象类
深复制与浅复制:需要一个和A完全相同新对象B,并且此后对B任何改动都不会影响到A中的值
- 浅复制表示复制目标对象本身,并不会复制目标对象的引用,所以B对A的引用C更改会影响到A中C的值
- 深复制表示复制目标对象本身,并且复制目标对象的引用,所以B对A的引用C更改会影响到A中C的值
强引用/软引用
容器
Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射。Collection 接口又有 3 种子类型,List(有重复)、Set(无重复) 和 Queue
List
ArrayList和Linklist、Vector的区别
- ArrayList是实现了基于动态数组的数据结构,LinkedList是基于链表结构。
- 对于get和set方法,ArrayList要优于LinkedList,因为LinkedList要移动指针。
- 对于add和remove,LinkedList比较占优势,因为ArrayList要移动数据。
- Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差
如果一直在list的尾部添加元素,用ArrayList和LinkedList哪个效率高?
- 当添加的数据量小于千万级别的时候,大部分是Linked效率高:当出现ArrayList扩容的时候,效率会降低
- 当数据量大于千万级别的时候,ArrayList的效率比较高:LinkedList每次增加的时候,会new一个Node对象,当数据量很大的时候,new对象的时间大于扩容的时间
Set
HashSet
- 包装了一个value全为空的HashMap,无序不重复
TreeSet
- 有序不重复,包装了一个value全为空的TreeMap
- 底层红黑树原理:添加和删除元素时都通过红黑树的插入和删除节点完成(O(log n)),效率比HashSet低(O(1))
Map
HashMap和 ConcurrentHashMap、HashTable的区别
- HashMap的键值对允许有null,但是ConCurrentHashMap/HashTable都不允许
- HashMap线程不安全,ConCurrentHashMap/HashTable线程安全
- HashTable将所有涉及到多线程操作的都加上了synchronized关键字来锁住整个table,而ConcurrentHashMap进行了分割分段(Segment),在每一个分段上都用lock锁进行保护,相对于HashTable的syn关键字锁的粒度更精细了一些,并发性能更好
ConcurrentHashMap的实现原理
- Concurrent HashMap底层用的分段锁,把一个大的Map拆分成N个小的HashTable,在put方法中,会根据hash(paramK.hashCode())来决定具体存放进哪个Segment,这样就可以对Map的一部分(Segment)进行lock操作上锁
- 1.7和1.8区别:JDK1.8的实现已经摒弃了Segment的概念,在 HashMap基础上改进,用Node数组+红黑树(代替链表)的数据结构来实现,并发控制使用Synchronized和CAS来操作(锁的粒度从segment降低为HashEntry)
HashMap内部具体如何实现的,负载因子为啥是2^n
- HashMap即是采用了链地址法避免哈希冲突,也就是数组+链表的方式
- 如果定位到的数组位置不含链表(当前entry的next指向null),那么对于查找,添加等操作很快,仅需一次寻址即可
- 如果定位到的数组包含链表,对于添加操作,其时间复杂度为O(n),首先遍历链表,存在即覆盖,否则新增;对于查找操作来讲,仍需遍历链表,然后通过key对象的equals方法逐一比对查找。
- 上面的h&(length-1)运算,由于(length-1)低位全为1,则h任何一位低位的变化都会对结果产生影响。要得到index=21这个存储位置,h的低位只有这一种组合;如果不是2的次幂,则(length-1)低位不是全为1,h的低位部分不再具有唯一性了,哈希冲突的几率会变的更大
迭代器
Iterator和ListIterator的区别是什么?
快速失败(fail-fast)和安全失败(fail-safe)的区别是什么?
为什么集合类没有实现Cloneable和Serializable接口?
多线程
多线程同步方法
java中的锁,悲观锁和乐观锁,自旋锁,分段锁等
CAS(ABA问题怎么解决)
voliate关键字
- 只能保证变量对所有线程的可见性(当一个线程修改了这个值,新值对于其他线程来说是立即可知的)
- 不能保证原子性
- 禁止指令重排序优化,在编译时会产生lock操作,相当于内存屏障,不能将后面的指令排到屏障之前
synchronized的底层实现原理
- synchronized在编译之后,会在同步块的前后分别形成monitorenter和monitorexit这两个指令。在执行monitorenter之前,首先要尝试获取对象的锁。如果这个对象没被锁定,或者当前线程已经拥有了对象的锁,把锁的计数器加1;相应的,在执monitorexit指令时会将锁计数器减1,当计数器为0时,锁就被释放。
synchronize与lock 的区别
- synchronized会自动释放锁(a 线程执行完同步代码会释放锁 ;b 线程执行过程中发生异常会释放锁),Lock需在finally中用unlock()方法手工释放锁,否则容易造成线程死锁;
- 用synchronized关键字的两个线程1和线程2,如果当前线程1获得锁,线程2线程等待。如果线程1阻塞,线程2则会一直等待下去,而Lock锁就不一定会等待下去,如果尝试获取不到锁,线程可以不用一直等待就结束了;
- synchronized的锁可重入、不可中断、非公平,而Lock锁可重入、可判断、可公平
- Lock锁适合大量同步的代码的同步问题,synchronized锁适合代码少量的同步问题。
wait和sleep和yield的区别
- sleep()针对的是当前线程,调用会暂停此线程指定的时间,不会释放对象锁,到时间自动恢复就绪状态;
- wait()针对的是被同步代码块加锁的对象,调用会释放对象锁,直到调用notify()/notifyAll()唤醒指定的线程或者所有线程,才会进入锁池,再次获得对象锁才会进入运行状态;wait方法必须在同步代码块中调用;
- yield()针对的也是当前线程,暂停当前正在执行的线程对象,来让有同样或更高优先级的正在等待的线程有机会执行。如果没有,那么该线程会继续运行
Java中有几种方式创建一个线程?哪种更好?为什么?
- 继承Thread类,实现runnable接口,通过Callable和Future创建线程三种。
- 后两者方式更好,线程类只是实现了Runnable接口或Callable接口,还可以继承其他类。在这种方式下,多个线程可以共享同一个target对象,所以非常适合多个相同线程来处理同一份资源的情况
线程池的好处?线程池的参数?有几种线程池?
- 好处1:使用线程池可以减少创建和销毁线程的次数,每个工作线程都可以重复使用。(当有工作来,就会向线程池拿一个线程,当工作完成后,并不是直接关闭线程,而是将这个线程归还给线程池,供其他任务使用)
- 好处2:可以根据系统的承受能力,调整线程池中工作线程的数量,防止因为消耗过多内存导致服务器崩溃。
- corePoolSize 线程池中的核心线程数
- maximumPoolSize 线程池中的最大线程数
- keepAliveTime 线程池中的线程存活时间(准确来说应该是没有任务执行时的回收时间)
- workQueue 一个阻塞队列,用来存储等待执行的任务
- threadFactory 新建woker线程(注意不是我们提交的任务)是进行一些属性设置,比如线程名,优先级等等,有默认实现。
- handler 任务拒绝策略,当运行线程数已达到maximumPoolSize,队列也已经装满时会调用该参数拒绝任务,有默认实现。
- 固定大小的线程池:池中的线程数量始终不变,当有新任务提交时,线程池中有空闲线程则会立即执行,如果没有,则会暂存到无界的阻塞队列。
- 单个线程池:只有一个线程的线程池,若有多余的任务提交到线程池中,则会被暂存到无界的阻塞队列,待空闲时再去执行。按照先入先出的顺序执行任务。
- 缓存线程池:缓存的线程默认存活60秒。阻塞队列使用的是SynchronousQueue。是一个直接提交的阻塞队列, 他总会迫使线程池增加新的线程去执行新的任务。在没有任务执行时,当线程的空闲时间超过keepAliveTime(60秒),则工作线程将会终止被回收。
- 定时线程池:该线程池可用于周期性地去执行任务,通常用于周期性的同步数据。
JVM
垃圾回收机制:GC-ROOT、 新生代和老年代的回收算法(什么时候是标记清除,什么时候标记整理,什么是复制算法,各有什么优缺点)
JVM(运行时数据区域,与JMM的区别)
clone是浅拷贝还是深拷贝?两种拷贝有什么区别?
框架
Spring,spring 事务,spring中用到哪些设计模式,AOP的原理,动态代理哪几种,区别
Mybatis(最常用,灵活简便)
设计模式
创建型模式:用于解耦对象的实例化过程。例如工厂模式。
结构型模式:把类或对象结合在一起形成一个更大的结构。
行为型模式:类和对象如何交互,及划分责任和算法。
数据库
MySQL,Oracle,Redis。MySQL是开源的关系型数据库,大部分公司用这个,而且面试都是问MySQL。Oracle收费的,银行用的比较多,二者都实现了标准的sql语句,把它搞定就行了。Redis是最常用非关系型数据库,学起来比MySQL容易些,上手快(String是如何插入到Redis)