1、说一下集中常见的排序算法和分别的复杂度
2、用java写一个冒泡排序算法
3、描述一下链式存储结构
4、如何遍历一棵二叉树
5、倒排一个LinkedList
6、用java写一个递归遍历目录下面的所有文件
java基础
1、接口和抽象类的区别
2、java中的异常有哪几类?分别怎么使用
Throwable是所有异常的根,java.lang.Throwable
Error:错误,Java.lang.Error
Exception:异常,java.lang.Exception
Exception分为CheckedException和RuntimeException,所有RuntimeException类及其子类的实例被称为Runtime异常,不属于该范畴的异常则被称为CheckedException。
对Checked异常处理方法有两种:
1、当前方法知道如何处理该异常,则用try…catch块来处理。
2、当前方法不知道如何处理,则在定义该方法时声明抛出该异常。
我们比较熟悉的Checked异常有
Java.lang.ClassNotFoundException
Java.lang.NoSuchMetodException
java.io.IOException
②RuntimeException
Runtime如除数是0和数组下标越界等,其产生频繁,处理麻烦,若显示申明或者捕获将会对程序的可读性和运行效率影响很大。所以由系统自动检测并将它们交给缺省的异常处理程序。当然如果你有处理要求也可以显示捕获它们
我们比较熟悉的RumtimeException类的子类有
Java.lang.ArithmeticException
Java.lang.ArrayStoreExcetpion
Java.lang.ClassCastException
Java.lang.IndexOutOfBoundsException
Java.lang.NullPointerException
3、常用的集合类有哪些?比如List如何排序?
List 接口有个 sort 方法
此方法如何传入一个Comparetor接口
该接口中的方法定义比较元素大小的方法,如
int compare(T o1, T o2);
说回sort方法
该方法先将list转成数组,然后调用数组Arrays工具类的排序方法
public static <T> void sort(T[] a, Comparator<? super T> c) {
if (c == null) {
sort(a);
} else {
if (LegacyMergeSort.userRequested)
legacyMergeSort(a, c);
else
TimSort.sort(a, 0, a.length, c, null, 0, 0);
}
}
方法先判断 调用方是否提供了 Comparator接口,前面我们知道该接口定义了比较元素大小的compara(a,b)方法
也就是说,如果调用方告诉了java如何比较元素大小,java就知道怎么进行排序了,因为排序无非就是要知道元素的大小,才能确定元素排在哪个位置。
如果调用方不提供Comparator接口,那么则调用Arrays工具类的默认方法
public static void sort(Object[] a) {
if (LegacyMergeSort.userRequested)
legacyMergeSort(a);
else
ComparableTimSort.sort(a, 0, a.length, null, 0, 0);
}
看到legacyMergeSort(a),就知道是使用归并排序了
4、ArrayList和LinkedList内部的实现大致是怎样?它们之间的区别和优缺点
1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
2.对于随机访问get和set,ArrayList优于LinkedList,因为ArrayList可以随机定位,而LinkedList要移动指针一步一步的移动到节点处。(参考数组与链表来思考)
3.对于新增和删除操作add和remove,LinedList比较占优势,只需要对指针进行修改即可,而ArrayList要移动数据来填补被删除的对象的空间。
三.总结
ArrayList和LinkedList在性能上各有优缺点,都有各自所适用的地方,总的说来可以描述如下:
性能总结:
1.对ArrayList和LinkedList而言,在列表末尾增加一个元素所花的开销都是固定的。对ArrayList而言,主要是在内部数组中增加一项,指向所添加的元素,偶尔可能会导致对数组重新进行分配;而对LinkedList而言,这个开销是统一的,分配一个内部Entry对象。
2.在ArrayList的中间插入或删除一个元素意味着这个列表中剩余的元素都会被移动;而在LinkedList的中间插入或删除一个元素的开销是固定的。
3.LinkedList不支持高效的随机元素访问。
4.ArrayList的空间浪费主要体现在在list列表的结尾预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间
可以这样说:当操作是在一列数据的后面添加数据而不是在前面或中间,并且需要随机地访问其中的元素时,使用ArrayList会提供比较好的性能;当你的操作是在一列数据的前面或中间添加或删除数据,并且按照顺序访问其中的元素时,就应该使用LinkedList了。
LinkedList类
LinkedList实现了List接口,允许null元素。此外LinkedList提供额外的get,remove,insert方法在LinkedList的首部或尾部。这些操作使LinkedList可被用作堆栈(stack),队列(queue)或双向队列(deque)。
注意LinkedList没有同步方法。如果多个线程同时访问一个List,则必须自己实现访问同步。一种解决方法是在创建List时构造一个同步的List:
List list = Collections.synchronizedList(new LinkedList(...));
ArrayList类
ArrayList实现了可变大小的数组。它允许所有元素,包括null。ArrayList没有同步。
size,isEmpty,get,set方法运行时间为常数。但是add方法开销为分摊的常数,添加n个元素需要O(n)的时间。其他的方法运行时间为线性。
每个ArrayList实例都有一个容量(Capacity),即用于存储元素的数组的大小。这个容量可随着不断添加新元素而自动增加,但是增长算法并没有定义。当需要插入大量元素时,在插入前可以调用ensureCapacity方法来增加ArrayList的容量以提高插入效率。
和LinkedList一样,ArrayList也是非同步的(unsynchronized)。
总结
如果涉及到堆栈,队列等操作,应该考虑用List,对于需要快速插入,删除元素,应该使用LinkedList,如果需要快速随机访问元素,应该使用ArrayList。
尽量返回接口而非实际的类型,如返回List而非ArrayList,这样如果以后需要将ArrayList换成LinkedList时,客户端代码不用改变。这就是针对抽象编程。
5、内存溢出是怎么回事?请举一个例子
对象有被指向的引用,但是再也用不到它就是内存溢出了。
GC机制:复制回收,标记清除,引用计数(如果有循环引用后,会影响垃圾回收,所以JVM虚拟机没有采用此方法进行垃圾回收)。
对于Java,内存溢出分三种情况。
1、OutOfMemoryError: PermGen space
Permanent Generation space 这个区域主要用来保存加来的Class的一些信息,在程序运行期间属于永久占用的,Java的GC不会对他进行释放,所以如果启动的程序加载的信息比较大,超出了这个空间的大小,就会发生溢出错误;
解决的办法无非就是增加空间分配了——增加java虚拟机中的XX:PermSize和XX:MaxPermSize参数的大小,其中XX:PermSize是初始永久保存区域大小,XX:MaxPermSize是最大永久保存区域大小。
2、OutOfMemoryError:Java heap space
heap 是Java内存中的堆区,主要用来存放对象,当对象太多超出了空间大小,GC又来不及释放的时候,就会发生溢出错误。
Java中对象的创建是可控的,但是对象的回收是由GC自动的,一般来说,当已存在对象没有引用(即不可达)的时候,GC就会定时的来回收对象,释放空间。但是因为程序的设计问题,导致对象可达但是又没有用(即前文提到的内存泄露),当这种情况越来越多的时候,问题就来了。
针对这个问题,我们需要做一下两点:
1、检查程序,减少大量重复创建对象的死循环,减少内存泄露。
2、增加Java虚拟机中Xms(初始堆大小)和Xmx(最大堆大小)参数的大小。
3、StackOverFlowError
stack是Java内存中的栈空间,主要用来存放方法中的变量,参数等临时性的数据的,发生溢出一般是因为分配空间太小,或是执行的方法递归层数太多创建了占用了太多栈帧导致溢出。
针对这个问题,除了修改配置参数-Xss参数增加线程栈大小之外,优化程序是尤其重要。
5、==和equals的区别
7、hashcode方法的作用
当集合要添加新的元素时,先调用这个元素的hashCode方法,就一下子能定位到它应该放置的物理位置上。
如果这个位置上没有元素,它就可以直接存储在这个位置上,不用再进行任何比较了;如果这个位置上已经有元素了,
就调用它的equals方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址。
所以这里存在一个冲突解决的问题。这样一来实际调用equals方法的次数就大大降低了,几乎只需要一两次。
8、NIO是什么?适用于何种场景
IO NIO
面向流 面向缓冲
阻塞IO 非阻塞IO
无 选择器
面向流与面向缓冲
Java NIO和IO之间第一个最大的区别是,IO是面向流的,NIO是面向缓冲区的。 Java IO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方。此外,它不能前后移动流中的数据。如果需要前后移动从流中读取的数据,需要先将它缓存到一个缓冲区。 Java NIO的缓冲导向方法略有不同。数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动。这就增加了处理过程中的灵活性。但是,还需要检查是否该缓冲区中包含所有您需要处理的数据。而且,需确保当更多的数据读入缓冲区时,不要覆盖缓冲区里尚未处理的数据。
阻塞与非阻塞IO
Java IO的各种流是阻塞的。这意味着,当一个线程调用read() 或 write()时,该线程被阻塞,直到有一些数据被读取,或数据完全写入。该线程在此期间不能再干任何事情了。 Java NIO的非阻塞模式,使一个线程从某通道发送请求读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取。而不是保持线程阻塞,所以直至数据变的可以读取之前,该线程可以继续做其他的事情。 非阻塞写也是如此。一个线程请求写入一些数据到某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情。 线程通常将非阻塞IO的空闲时间用于在其它通道上执行IO操作,所以一个单独的线程现在可以管理多个输入和输出通道(channel)。
9、HashMap实现原理,如何保证HashMap的线程安全 List如何保证线程安全
使用 java.util.Hashtable 类,此类是线程安全的。
使用 java.util.concurrent.ConcurrentHashMap,此类是线程安全的。
使用 java.util.Collections.synchronizedMap() 方法包装 HashMap object,得到线程安全的Map,并在此Map上进行操作。
1、new Vector
2、Collections.synchronizedMap(m)
3、CopyOnWriteArrayList<E>
10、jvm内存结构,为什么需要GC
11、NIO模型,select/epoll的区别,多路复用的原理
12、java中一个字符占多少字节,扩展再问int long double占多少字节
一个字符两个字节,int 4 , long double 8
13、创建一个类的实例有哪些办法
1、关键字 new。工厂模式是对这种方式的包装;
2、类实现克隆接口,克隆一个实例。原型模式是一个应用实例;
3、用该类的加载器,newinstance。java的反射,反射使用实例:Spring的依赖注入、切面编程中动态代理
4、sun.misc.Unsafe类,allocateInstance方法创建一个实例。(Java官方也不建议直接使用的Unsafe类,据说Oracle正在计划从Java 9中去掉Unsafe类)
5、实现序列化接口的类,通过IO流反序列化读取一个类,获得实例。
14、final/finaly/finalize的区别
15、session和cookie的区别
16、String/StringBuffer/StringBuilder的区别 以及实现
17、servlet生命周期
- Servlet 通过调用 init () 方法进行初始化。
- Servlet 调用 service() 方法来处理客户端的请求。
- Servlet 通过调用 destroy() 方法终止(结束)。
- 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。
18、如何用java分配一段连续1G的内存空间?需要注意什么
ByteBuffer.allocateDirect(1024*1024*1024);
19、java有自己的内存回收机制,但为什么还存在内存泄漏的问题呢?
20、什么是java序列化,如何实现java序列化
21、tomcat类加载机制
https://blog.csdn.net/moni_mm/article/details/82081234
JVM
- · JVM堆的基本结构。
- · JVM的垃圾算法有哪几种?CMS垃圾回收的基本流程?
- · JVM有哪些常用启动参数可以调整,描述几个?
- · 如何查看JVM的内存使用情况?
- · Java程序是否会内存溢出,内存泄露情况发生?举几个例子。
- · 你常用的JVM配置和调优参数都有哪些?分别什么作用?
- · JVM的内存结构?
- · 常用的GC策略,什么时候会触发YGC,什么时候触发FGC?
四、多线程/并发
- · 如何创建线程?如何保证线程安全?
- · 如何实现一个线程安全的数据结构
- · 如何避免死锁
- · Volatile关键字的作用?
- · HashMap在多线程环境下使用需要注意什么?为什么?
- · Java程序中启动一个线程是用run还是start?
- · 什么是守护线程?有什么用?
- · 什么是死锁?如何避免
- · 线程和进程的差别是什么?
- · Java里面的Threadlocal是怎样实现的?
- · ConcurrentHashMap的实现原理是?
- · sleep和wait区别
- · notify和notifyAll区别
- · volatile关键字的作
- · ThreadLocal的作用与实现
- · 两个线程如何串行执行
- · 上下文切换是什么含义
- · 可以运行时kill掉一个线程吗?
- · 什么是条件锁、读写锁、自旋锁、可重入锁?
- · 线程池ThreadPoolExecutor的实现原理?
五、Linux使用与问题分析排查
- · 使用两种命令创建一个文件?
- · 硬链接和软链接的区别?
- · Linux常用命令有哪些?
- · 怎么看一个Java线程的资源耗用?
- · Load过高的可能性有哪些?
- · /etc/hosts文件什么做用?
- · 如何快速的将一个文本中所有“abc”替换为“xyz”?
- · 如何在log文件中搜索找出error的日志?
- · 发现磁盘空间不够,如何快速找出占用空间最大的文件?
- · Java服务端问题排查(OOM,CPU高,Load高,类冲突)
- · Java常用问题排查工具及用法(top, iostat, vmstat, sar, tcpdump, jvisualvm, jmap, jconsole)
- · Thread dump文件如何分析(Runnable,锁,代码栈,操作系统线程ID关联)
- · 如何查看Java应用的线程信息?
六、框架使用
- · 描述一下Hibernate的三个状态?
- · Spring中Bean的生命周期。
- Spring启动,查找并加载需要被Spring管理的bean,进行Bean的实例化
- Bean实例化后对将Bean的引入和值注入到Bean的属性中
- 如果Bean实现了BeanNameAware接口的话,Spring将Bean的Id传递给setBeanName()方法
- 如果Bean实现了BeanFactoryAware接口的话,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入
- 如果Bean实现了ApplicationContextAware接口的话,Spring将调用Bean的setApplicationContext()方法,将bean所在应用上下文引用传入进来。
- 如果Bean实现了BeanPostProcessor接口,Spring就将调用他们的postProcessBeforeInitialization()方法。
- 如果Bean 实现了InitializingBean接口,Spring将调用他们的afterPropertiesSet()方法。类似的,如果bean使用init-method声明了初始化方法,该方法也会被调用
- 如果Bean 实现了BeanPostProcessor接口,Spring就将调用他们的postProcessAfterInitialization()方法。
- 此时,Bean已经准备就绪,可以被应用程序使用了。他们将一直驻留在应用上下文中,直到应用上下文被销毁。
- 如果bean实现了DisposableBean接口,Spring将调用它的destory()接口方法,同样,如果bean使用了destory-method 声明销毁方法,该方法也会被调用。
- · SpringMVC或Struts处理请求的流程。
- · Spring AOP解决了什么问题?怎么实现的?
- · Spring事务的传播属性是怎么回事?它会影响什么?
- · Spring中BeanFactory和FactoryBean有什么区别?
- · Spring框架中IOC的原理是什么?
- · spring的依赖注入有哪几种方式
- · struts工作流程
- · 用Spring如何实现一个切面?
- · Spring 如何实现数据库事务?
- · Hibernate对一二级缓存的使用,Lazy-Load的理解;
- · mybatis如何实现批量提交?
七、数据库相关
- · MySQL InnoDB、Mysaim的特点?
- · 乐观锁和悲观锁的区别?
- · 数据库隔离级别是什么?有什么作用?
- · MySQL主备同步的基本原理。
- · select * from table t where size > 10 group by size order by size的sql语句执行顺序?
- · 如何优化数据库性能(索引、分库分表、批量操作、分页算法、升级硬盘SSD、业务优化、主从部署)
- · SQL什么情况下不会使用索引(不包含,不等于,函数)
- · 一般在什么字段上建索引(过滤数据最多的字段)
- · 如何从一张表中查出name字段不包含“XYZ”的所有行?
- · MySQL,B+索引实现,行锁实现,SQL优化
- · Redis,RDB和AOF,如何做高可用、集群
- · 如何解决高并发减库存问题
- · mysql存储引擎中索引的实现机制;
- · 数据库事务的几种粒度;
- · 行锁,表锁;乐观锁,悲观锁
八、网络协议和网络编程
- · TCP建立连接的过程。
- · TCP断开连接的过程。
- · 浏览器发生302跳转背后的逻辑?
- · HTTP协议的交互流程。HTTP和HTTPS的差异,SSL的交互流程?
- · Rest和Http什么关系?大家都说Rest很轻量,你对Rest风格如何理解?
- · TCP的滑动窗口协议有什么用?讲讲原理。
- · HTTP协议都有哪些方法?
- · 交换机和路由器的区别?
- · Socket交互的基本流程?
- · 协议(报文结构,断点续传,多线程下载,什么是长连接)
- · tcp协议(建连过程,慢启动,滑动窗口,七层模型)
- · webservice协议(wsdl/soap格式,与rest协议的区别)
- · NIO的好处,Netty线程模型,什么是零拷贝
九、Redis等缓存系统/中间件/NoSQL/一致性Hash等
- · 列举一个常用的Redis客户端的并发模型。
- · HBase如何实现模糊查询?
- · 列举一个常用的消息中间件,如果消息要保序如何实现?
- · 如何实现一个Hashtable?你的设计如何考虑Hash冲突?如何优化?
- · 分布式缓存,一致性hash
- · LRU算法,slab分配,如何减少内存碎片
- · 如何解决缓存单机热点问题
- · 什么是布隆过滤器,其实现原理是? False positive指的是?
- · memcache与redis的区别
- · zookeeper有什么功能,选举算法如何进行
- · map/reduce过程,如何用map/reduce实现两个数据源的联合统计
十、设计模式与重构
- · 你能举例几个常见的设计模式
- · 你在设计一个工厂的包的时候会遵循哪些原则?
- · 你能列举一个使用了Visitor/Decorator模式的开源项目/库吗?
- · 你在编码时最常用的设计模式有哪些?在什么场景下用?
- · 如何实现一个单例?
- · 代理模式(动态代理)
- · 单例模式(懒汉模式,恶汉模式,并发初始化如何解决,volatile与lock的使用)
- · JDK源码里面都有些什么让你印象深刻的设计模式使用,举例看看?
十一:微服务
1、什么是微服务?
2、微服务之间是如何独立通讯的
3、springCloud和dubbo 有哪些区别?
4、springboot和springcloud,请你谈谈对他们的理解?
5、什么是微服务熔断?什么是服务降级?
6、微服务的优缺点分别是什么?说下你在项目开发中碰到的坑
7、你所知道的微服务技术栈有哪些?请列举一二
8、eureka和zookeeper都可以提供服务的注册和发现的功能,请说说两个的区别?