2019为面试总结面试题

1.开发中Java用了比较多的数据结构有哪些?html

 

 

 

java中有几种经常使用的数据结构,主要分为Collection和map两个主要接口(接口只提供方法,并不提供实现),而程序中最终使用的数据结构是继承自这些接口的数据结构类;java

List

List是有序的Collection,使用此接口可以精确的控制每一个元素插入的位置。用户可以使用索引(元素在List中的位置,相似于数组下 >标)来访问List中的元素,这相似于Java的数组。 redis

Vector

基于数组(Array)的List,其实就是封装了数组所不具有的一些功能方便咱们使用,因此它难易避免数组的限制,同时性能也不可能超越数组。因此,在可能的状况下,咱们要多运用数组。另外很重要的一点就是Vector是线程同步的(sychronized)的,这也是Vector和ArrayList 的一个的重要区别。数组

ArrayList

同Vector同样是一个基于数组上的链表,可是不一样的是ArrayList不是同步的。因此在性能上要比Vector好一些,可是当运行到多线程环境中时,可须要本身在管理线程的同步问题。浏览器

LinkedList

LinkedList不一样于前面两种List,它不是基于数组的,因此不受数组性能的限制。 
它每个节点(Node)都包含两方面的内容: 
1.节点自己的数据(data); 
2.下一个节点的信息(nextNode)。 
因此当对LinkedList作添加,删除动做的时候就不用像基于数组的ArrayList同样,必须进行大量的数据移动。只要更改nextNode的相关信息就能够实现了,这是LinkedList的优点。缓存

List总结

  • 全部的List中只能容纳单个不一样类型的对象组成的表,而不是Key-Value键值对。例如:[ tom,1,c ]
  • 全部的List中能够有相同的元素,例如Vector中能够有 [ tom,koo,too,koo ]
  • 全部的List中能够有null元素,例如[ tom,null,1 ]

     基于Array的List(Vector,ArrayList)适合查询,而LinkedList 适合添加,删除操做tomcat

Set(Set是不包含重复元素的Collection)

HashSet

虽然Set同List都实现了Collection接口,可是他们的实现方式却大不同。List基本上都是以Array为基础。可是Set则是在 HashMap的基础上来实现的,这个就是Set和List的根本区别。HashSet的存储方式是把HashMap中的Key做为Set的对应存储项。看看 HashSet的add(Object obj)方法的实现就能够一目了然了。安全

LinkedHashSet

HashSet的一个子类,一个链表。服务器

SortedSet

有序的Set,经过SortedMap来实现的。cookie

Set总结:

1)Set实现的基础是Map(HashMap)(2)Set中的元素是不能重复的,若是使用add(Object obj)方法添加已经存在的对象,则会覆盖前面的对象

 

HashMap

API ----基于Hash表的Map  接口实现。此实现提供全部可选的映射操做,并容许  值和    键。(  HashMap 类大体至关于Hashtable,除了它是不一样步的而且容许空值。)这个类不保证地图的顺序; 特别是,它不保证订单会随着时间的推移保持不变。  

TreeMap

API ----基于红黑树的 NavigableMap  实现。地图根据 其键 天然顺序进行排序 ,或者 Comparator  根据使用的构造函数在地图建立时提供。 
TreeMap则是对键按序存放,所以它便有一些扩展的方法,好比firstKey(),lastKey()等,你还能够从TreeMap中指定一个范围以取得其子Map。 
键和值的关联很简单,用put(Object key,Object value)方法便可将一个键与一个值对象相关联。用get(Object key)可获得与此key对象所对应的值对象。 
 
HashMap:适用于在Map中插入、删除和定位元素。
Treemap:适用于按天然顺序或自定义顺序遍历键(key)
 
1、几个经常使用类的区别 
1.ArrayList: 元素单个,效率高,多用于查询 
2.Vector: 元素单个,线程安全,多用于查询 
3.LinkedList:元素单个,多用于插入和删除 
4.HashMap: 元素成对,元素可为空 
5.HashTable: 元素成对,线程安全,元素不可为空 
2、Vector、ArrayList和LinkedList 
大多数状况下,从性能上来讲ArrayList最好,可是当集合内的元素须要频繁插入、删除时LinkedList会有比较好的表现,可是它们三个性能都比不上数组,另外Vector是线程同步的。因此: 
若是能用数组的时候(元素类型固定,数组长度固定),请尽可能使用数组来代替List; 
若是没有频繁的删除插入操做,又不用考虑多线程问题,优先选择ArrayList; 
若是在多线程条件下使用,能够考虑Vector; 
若是须要频繁地删除插入,LinkedList就有了用武之地; 
若是你什么都不知道,用ArrayList没错。 
 
谈谈你对HashMap的理解,底层原理的基本实现,HashMap怎么解决碰撞问题的?
https://blog.csdn.net/weixin_37751634/article/details/82882222
 
http协议,get和post的基本区别?
  • get(默认值)是经过URL传递表单值,数据追加在action属性后面。
  • post传递的表单值是隐藏到http报文体中,url中看不到。
  • get是经过url传递表单值,post经过url看不到表单域的值;
  • get传递的数据量是有限的,若是要传递大数据量不能用get,好比type=“file”上传文章、type=“password”传递密码或者<textarea>发表大段文章,post则没有这个限制。
  • post区别:网址隐藏;只要当前页面请求是POST请求,那么刷新就是从新发出POST,部分浏览器会提示“是否重复提交”。
  • 只要在地址栏中输入一个网址回车访问,那么就是GET。精确到具体网页

数据格式。服务端文件名后跟着“?”,因为客户端可能向服务器端提交多个键值对,键值对之间用“&”进行分割,若是URL中有汉字、特殊符号等,则须要对URL进行编码。

Http协议定义了不少与服务器交互的方法,最基本的有4种,分别是GET,POST,PUT,DELETE. 一个URL地址用于描述一个网络上的资源,而HTTP中的GET, POST, PUT, DELETE就对应着对这个资源的查,改,增,删4个操做。 咱们最多见的就是GET和POST了。GET通常用于获取/查询资源信息,而POST通常用于更新资源信息.

咱们看看GET和POST的区别

1. GET提交的数据会放在URL以后,以?分割URL和传输数据,参数之间以&相连,如EditPosts.aspx?name=test1&id=123456.(注意对于用户登陆来讲,get是不安全的,网页直接显示你的用户名和密码) POST方法是把提交的数据放在HTTP包的Body中.

2. GET提交的数据大小有限制(由于浏览器对URL的长度有限制),而POST方法提交的数据没有限制.

3. GET方式须要使用Request.QueryString来取得变量的值,而POST方式经过Request.Form来获取变量的值。

4. GET方式提交数据,会带来安全问题,好比一个登陆页面,经过GET方式提交数据时,用户名和密码将出如今URL上,若是页面能够被缓存或者其余人能够访问这台机器,就能够从历史记录得到该用户的帐号和密码.

tcp/ip协议,三次握手,窗口滑动机制:

 https://www.cnblogs.com/wen-ge/articles/5819778.html

悲观锁和乐观锁问题使用场景?

悲观锁:比较适合写入操做比较频繁的场景,若是出现大量的读取操做,每次读取的时候都会进行加锁,这样会增长大量的锁的开销,下降了系统的吞吐量。

乐观锁:比较适合读取操做比较频繁的场景,若是出现大量的写入操做,数据发生冲突的可能性就会增大,为了保证数据的一致性,应用层须要不断的从新获取数据,这样会增长大量的查询操做,下降了系统的吞吐量。

总结:两种所各有优缺点,读取频繁使用乐观锁,写入频繁使用悲观锁。

分布式session的几种实现方式

第一种:粘性session

原理:粘性Session是指将用户锁定到某一个服务器上,好比上面说的例子,用户第一次请求时,负载均衡器将用户的请求转发到了A服务器上,若是负载均衡器设置了粘性Session的话,那么用户之后的每次请求都会转发到A服务器上,至关于把用户和A服务器粘到了一块,这就是粘性Session机制。

优势:简单,不须要对session作任何处理。

缺点:缺少容错性,若是当前访问的服务器发生故障,用户被转移到第二个服务器上时,他的session信息都将失效。

适用场景:发生故障对客户产生的影响较小;服务器发生故障是低几率事件。

第二种:服务器session复制

原理:任何一个服务器上的session发生改变(增删改),该节点会把这个 session的全部内容序列化,而后广播给全部其它节点,无论其余服务器需不须要session,以此来保证Session同步。

优势:可容错,各个服务器间session可以实时响应。

第三种:session共享机制

使用分布式缓存方案好比memcachedRedis,可是要求Memcached或Redis必须是集群。

使用Session共享也分两种机制,两种状况以下:

① 粘性session处理方式

原理:不一样的 tomcat指定访问不一样的主memcached。多个Memcached之间信息是同步的,能主从备份和高可用。用户访问时首先在tomcat中建立session,而后将session复制一份放到它对应的memcahed上。memcache只起备份做用,读写都在tomcat上。当某一个tomcat挂掉后,集群将用户的访问定位到备tomcat上,而后根据cookie中存储的SessionId找session,找不到时,再去相应的memcached上去session,找到以后将其复制到备tomcat上。

② 非粘性session处理方式

原理:memcached作主从复制,写入session都往从memcached服务上写,读取都从主memcached读取,tomcat自己不存储session

缺点:会对网络负荷形成必定压力,若是session量大的话可能会形成网络堵塞,拖慢服务器性能。

JVM老年代和新生代的比例?2:1

JVM虚拟机 YGC和FGC发生的具体场景

一、YGC和FGC是什么 

   YGC :对新生代堆进行gc。频率比较高,由于大部分对象的存活寿命较短,在新生代里被回收。性能耗费较小。

   FGC :全堆范围的gc。默认堆空间使用到达80%(可调整)的时候会触发fgc。

二、何时执行YGC和FGC

   一、eden空间不足,执行 young gc

   二、old空间不足,perm空间不足,调用方法System.gc() ,ygc时的悲观策略, dump live的内存信息时(jmap –dump:live),都会执行full gc

如何保证共享变量修改时的原子性?

使用synchronized(低效,使用悲观锁)、volatile修饰符来保证变量的可见性

Jdk5后提出了atomic 原子操做也能够保证可见性(高效且不须要使用同步,基于CAS)

Volatile和synchronized区别:

Volatile只是保证变量可见性,并不能确保原子性,它是依赖CPU提供的特殊指令内存屏障指令来控制可见性,被Volatile修饰的成员变量在被线程访问时在读操做前会强行插入一条内存屏障读指令强行从主存中读取(让高速缓存中的数据失效,从新从主内存加载数据),变量在被线程修改时会在写指令以后插入写屏障,让写入缓存的最新数据写回到主内存。

不能确保原子性,是由于若是A线程和B线程同时读取到变量a值,A线程修改a后将值刷到主存、同时B线程也修改了a的值并刷到主存,这时候B线程就覆盖了A线程修改操做。

Synchronized是经过对线程加锁(独占锁)控制线程同步,被Synchronized修饰的内存只容许一个线程访问

线程池的构造类的方法的5个参数的具体意义?

corePoolSize
核心线程数,核心线程会一直存活,即便没有任务须要处理。当线程数小于核心线程数时,即便现有的线程空闲,线程池也会优先建立新线程来处理任务,而不是直接交给现有的线程处理。

核心线程在allowCoreThreadTimeout被设置为true时会超时退出,默认状况下不会退出。

maxPoolSize
当线程数大于或等于核心线程,且任务队列已满时,线程池会建立新的线程,直到线程数量达到maxPoolSize。若是线程数已等于maxPoolSize,且任务队列已满,则已超出线程池的处理能力,线程池会拒绝处理任务而抛出异常。
keepAliveTime
当线程空闲时间达到keepAliveTime,该线程会退出,直到线程数量等于corePoolSize。若是allowCoreThreadTimeout设置为true,则全部线程均会退出直到线程数量为0。

allowCoreThreadTimeout
是否容许核心线程空闲退出,默认值为false。

queueCapacity
任务队列容量。从maxPoolSize的描述上能够看出,任务队列的容量会影响到线程的变化,所以任务队列的长度也须要恰当的设置。

详细见:https://blog.csdn.net/u011109589/article/details/80532796

单机上一个线程正在处理服务,若是突然断电了怎么办

咱们能够对正在处理和阻塞队列的任务作事物管理或者对阻塞队列中的任务持久化处理,而且当断电或者系统崩溃,操做没法继续下去的时候,能够经过回溯日志的方式来撤销正在处理的已经执行成功的操做。而后从新执行整个阻塞队列。

阻塞队列持久化,正在处理事物控制。断电以后正在处理的回滚,日志恢复该次操做。服务器重启后阻塞队列中的数据再加载

 防止接口重复请求

1.在data里定义一个初始状态,设为false,做为加载标志

2.请求以前将状态变成true,再去请求接口,这时一直是加载状态

3.当接口响应以后不论是成功仍是失败都将状态变成false

4.每次请求以前都判断一下加载状态,若是是true直接return

相关文章
相关标签/搜索