京东Java面试题总结及答案
分类:Java面试题 热度:

  自己最近在为找工作做准备,总结了一下公司的面经,主要来源是牛客上17年秋招面经的一个总结帖:链接在这里。
 
  感谢各位贡献面经的同学以及牛妹的总结,我做的工作就是把问题收集起来,并一个个找到我认为还不错的答案,所以这个过程中也很感谢互联网的各个博客的博主贡献的相关知识。
        
         
 
  因为才准备两周多,总结的不全,后续会持续更新,直到明年毕业,希望能帮助到跟我一样还在苦逼复习找工作的同学,加油,祝大家好运,也祝自己好运,希望来年春招能进入我心仪的公司。
 
  明年就2017年了,新的一年期待努力后能有收获。扯远了,上主菜:
 
  1.Spring的事务有哪些?
 
  什么是数据库事务:访问并可能改变数据库中个数据项的一个程序执行单元。
 
  实现方式共有两种:编码方式即采用注解的方式(类头的 Transactional为默认事务配置);声明式事务管理方式(bean)。
 
  基于AOP技术实现的声明式事务管理,实质就是:在方法执行前后进行拦截,然后在目标方法开始之前创建并加入事务,执行完目标方法后根据执行情况提交或回滚事务。
 
  声明式事务管理又有两种方式:基于XML配置文件的方式;另一个是在业务方法上进行 Transactional注解,将事务规则应用到业务逻辑中。
 
  2.Java的锁有哪几种?
 
  1、自旋锁:自旋锁是采用让当前线程不停地的在循环体内执行实现的,当循环的条件被其他线程改变时才能进入临界区。
 
  2、自旋锁的其他种类
 
  3、阻塞锁:常用的有五个状态的锁都是阻塞所。
 
  4、可重入锁:ReentrantLock
 
  5、读写锁:写锁是排他锁,读锁是共享锁。
 
  6、互斥锁
 
  7、悲观锁:在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制。
 
  8、乐观锁:乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做。
 
  公平锁(Fair):加锁前检查是否有排队等待的线程,优先排队等待的线程,先来先得
 
  非公平锁(Nonfair):加锁时不考虑排队等待问题,直接尝试获取锁,获取不到自动到队尾等待
 
  18、信号量
 
  3.join的优势是什么?
 
  mysql不支持Full join。
 
  select*from A inner join B on A.name=B.name;
 
  在ON匹配阶段WHERE子句的条件都不会被使用。仅在匹配阶段完成以后,WHERE子句条件才会被使用。它将从匹配阶段产生的数据中检索过滤。
 
  cross join:交叉连接,得到的结果是两个表的乘积,即笛卡尔积。
 
  还有inner join,left join,right join。
 
  4.用线程实现输出1A2B3C....
 
  5.抽象类和接口的区别
 
  6.JDK1.8和之前版本的区别
 
  JDK7新特性:
 
  1,switch中可以使用字串了
 
  2,"<>"这个玩意儿的运用List<String>tempList=new ArrayList<>();即泛型实例化类型自动推断
 
  3.自定义自动关闭类
 
  4.新增一些取环境信息的工具方法
 
  5.Boolean类型反转,空指针安全,参与位运算
 
  6.两个char间的equals
 
  7,安全的加减乘除
 
  8.数值可加下划线
 
  例如:int one_million=1_000_000;
 
  9.支持二进制文字
 
  例如:int binary=0b1001_1001;
 
  10、在try catch异常扑捉中,一个catch可以写多个异常类型,用"|"隔开
 
  11、jdk7之前,你必须用try{}finally{}在try内使用资源,在finally中关闭资源,不管try中的代码是否正常退出或者异常退出。jdk7之后,你可以不必要写finally语句来关闭资源,只要你在try()的括号内部定义要使用的资源。
 
  JDK8:
 
  一、接口的默认方法
 
  Java 8允许我们给接口添加一个非抽象的方法实现,只需要使用default关键字即可,这个特征又叫做扩展方法
 
  二、Lambda表达式
 
  Collections.sort(names,(a,b)->b.compareTo(a));
 
  三、函数式接口?
 
  四、方法与构造函数引用::
 
  Java 8在包java.time下包含了一组全新的时间日期API。
 
  7.常用集合类
 
  我的说的HashMap,他问为什么不是List。
 
  1。JSP的内置对象及方法。
 
  在JSP中无需创建就可以使用的9个对象,它们是:request、response、session、application、out、pagecontext、config、page、exception
 
  l out(JspWriter):等同与response.getWriter(),用来向客户端发送文本数据;
 
  1.void clear();
 
  清除输出缓冲区的内容,但是不输出到客户端。
 
  2.void clearBuffer();
 
  清除输出缓冲区的内容,并输出到客户端。
 
  3.void close();
 
  关闭输出流,清除所有内容。
 
  4.void flush();
 
  输出缓冲区里面的数据。
 
  5.int getBufferSize();
 
  获取以kb为单位的目前缓冲区大小。
 
  6.int getRemaining();
 
  获取以kb为单位的缓冲区中未被占用的空间大小。
 
  7.boolean isAutoFlush();
 
  是否自动刷新缓冲区。
 
  8.void newLine();
 
  输出一个换行字符。
 
  l config(ServletConfig):对应“真身”中的ServletConfig,config对象用来存放Servlet初始的数据结构;config
 
  对象的主要作用是取得服务器的配置信息。通过pageConext对象的getServletConfig()方法可以获取一个config对象。当一个Servlet初始化时,容器把某些信息通过config对象传递给这个Servlet。
 
  l page(当前JSP的真身类型):当前JSP页面的“this”,即当前对象,page对象代表JSP对象本身,或者说代表编译后的servlet对象,可以用(
 
  (javax.servlet.jsp.HttpJspPage)page)来取用它的方法和属性;
 
  l pageContext(PageContext):页面上下文对象,它是最后一个没讲的域对象,pageContext对象存储本JSP页面相关信息,如属性、内建对象等;pageContext
 
  对象的作用是取得任何范围的参数,通过它可以获取JSP页面的out、request、reponse、session、application等对象。
 
  l exception(Throwable):只有在错误页面中可以使用这个对象,错误对象,只有在JSP页面的page指令中指定isErrorPage="true"后,才可以在本页面使用exception对象;
 
  l request(HttpServletRequest):即HttpServletRequest类的对象,request对象包含所有请求的信息,如请求的来源、标头、cookies和请求相关的参数值等,request对象代表了客户端的请求信息,主要用于接受通过HTTP协议传送到服务器的数据。(包括头信息、系统信息、请求方式以及请求参数等)。request对
 
  象的作用域为一次请求。;
 
  getParameterNames()获取客户端提交的所有参数的名字。
 
  l response(HttpServletResponse):即HttpServletResponse类的对象,response对象主要将JSP容器处理后的结果传回到客户端,response
 
  代表的是对客户端的响应,主要是将JSP容器处理过的对象传回到客户端。response对象也具有作用域,它只在JSP页面内有效;
 
  response.sendRedirect(index.jsp)
 
  l application(ServletContext):即ServletContext类的对象,主要功用在于取得或更改Servlet的设定;
 
  setAttribute(String key,Object obj):将参数Object指定的对象obj添加到Application对象中,并为添加的对象指定一个索引关键字。
 
  getAttribute(String key):获取Application对象中含有关键字的对象。
 
  l session(HttpSession):即HttpSession类的对象,不是每个JSP页面中都可以使用,如果在某个JSP页面中设置<% page session=”false”%>,说明这个页面不能使用session,session对象表示目前个别用户的会话状态,用来识别每个用户。
 
  public String getId():获取Session对象编号。
 
  public void setAttribute(String key,Object obj):将参数Object指定的对象obj添加到Session对象中,并为添加的对象指定一个索引关键字。
 
  public Object getAttribute(String key):获取Session对象中含有关键字的对象。
 
  public Boolean isNew():判断是否是一个新的客户。
 
  2.说说ArrayList(对比着LinkedList来说);
 
  1.ArrayList是实现了基于动态数组的数据结构,ArrayList不具有线程安全性,LinkedList基于链表的数据结构,LinkedList可以看做为一个双向链表,LinkedList也是线程不安全的。
 
  2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
 
  3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
 
  Vector是线程安全的
 
  26.数组(Array)和列表(ArrayList)有什么区别?什么时候应该使用Array而不是ArrayList?
 
  下面列出了Array和ArrayList的不同点:
 
  Array可以包含基本类型和对象类型,ArrayList只能包含对象类型。
 
  Array大小是固定的,ArrayList的大小是动态变化的。
 
  ArrayList提供了更多的方法和特性,比如:addAll(),removeAll(),iterator()等等。
 
  对于基本类型数据,集合使用自动装箱来减少编码工作量。但是,当处理固定大小的基本数据类型的时候,这种方式相对比较慢。
 
  27.ArrayList和LinkedList有什么区别?
 
  ArrayList和LinkedList都实现了List接口,他们有以下的不同点:
 
  ArrayList是基于索引的数据接口,它的底层是数组。它可以以O(1)时间复杂度对元素进行随机访问。与此对应,LinkedList是以元素列表的形式存储它的数据,每一个元素都和它的前一个和后一个元素链接在一起,在这种情况下,查找某个元素的时间复杂度是O(n)。
 
  相对于ArrayList,LinkedList的插入,添加,删除操作速度更快,因为当元素被添加到集合任意位置的时候,不需要像数组那样重新计算大小或者是更新索引。
 
  LinkedList比ArrayList更占内存,因为LinkedList为每一个节点存储了两个引用,一个指向前一个元素,一个指向下一个元素。
 
  28.Comparable和Comparator接口是干什么的?列出它们的区别。
 
  Java提供了只包含一个compareTo()方法的Comparable接口。这个方法可以个给两个对象排序。具体来说,它返回负数,0,正数来表明输入对象小于,等于,大于已经存在的对象。
 
  Java提供了包含compare()和equals()两个方法的Comparator接口。compare()方法用来给两个输入参数排序,返回负数,0,正数表明第一个参数是小于,等于,大于第二个参数。equals()方法需要一个对象作为参数,它用来决定输入参数是否和comparator相等。只有当输入参数也是一个comparator并且输入参数和当前comparator的排序结果是相同的时候,这个方法才返回true。
 
  3.写一个单例模式。我写的是静态内部类的单例,然后他问我这个地方为什么用private,这儿为啥用static,这就考察你的基本功啦
 
  类的构造函数定义为private的,保证其他类不能实例化此类,static保证每个类访问到的都是同一个。
 
  饿汉模式:
 
  public class Singleton{
 
  private static Singleton instance=new Singleton();
 
  private Singleton(){}
 
  public static Singleton newInstance(){
 
  return instance;
 
  }
 
  }缺点,在类加载之后就被创建,即使没有用到
 
  懒汉模式:
 
  public class Singleton{
 
  private static Singleton instance=null;
 
  private Singleton(){}
 
  public static synchronized Singleton newInstance(){
 
  if(null==instance){
 
  instance=new Singleton();
 
  }
 
  return instance;
 
  }
 
  }在特定时间加载,延迟加载
 
  双重校验锁:
 
  public class Singleton{
 
  private static volatile Singleton instance=null;
 
  private Singleton(){}
 
  public static Singleton getInstance(){
 
  if(instance==null){
 
  synchronized(Singleton.class){
 
  if(instance==null){//2
 
  instance=new Singleton();
 
  }
 
  }
 
  }
 
  return instance;
 
  }
 
  }线程安全
 
  静态内部类:
 
  public class Singleton{
 
  private static class SingletonHolder{
 
  public static Singleton instance=new Singleton();
 
  }
 
  private Singleton(){}
 
  public static Singleton newInstance(){
 
  return SingletonHolder.instance;
 
  }
 
  }
 
  枚举:
 
  public enum Singleton{
 
  instance;
 
  public void whateverMethod(){}
 
  }很少使用
 
  4.给了一个表三个字段,写SQL语句。主要考察基本SQL语句语法、聚集函数和Group By的用法
 
  姓名分数课程
 
  name score course
 
  统计出每个学生有多少门课分数大于80分
 
  select name,count(*)as num from student where score>80 group by name;
 
  5.说一说GC算法吧。
 
  http://www.cnblogs.com/hnrainll/archive/2013/11/06/3410042.html(讲到了minor
 
  GC)
 
  当两个存活区切换了几次(HotSpot虚拟机默认15次,用-XX:MaxTenuringThreshold控制,大于该值进入老年代)之后,仍然存活的对象(其实只有一小部分,比如,我们自己定义的对象),将被复制到老年代。Eden区与Survivor的比例较大,HotSpot默认是
 
  8:1。在发生Minor GC时,虚拟机会检查每次晋升进入老年代的大小是否大于老年代的剩余空间大小,如果大于,则直接触发一次Full GC。
 
  1)从JVM内存模型开始说起,在纸上画出大概的组成部分,然后说出每个组成部分的特点
 
  线程隔离的有:虚拟机栈,本地方法栈和程序计数器;
 
  线程共享的有:方法区(被虚拟机加载的类的元数据信息:如常量、静态变量、即时编译器编译后的代码。也成为永久代)和堆区(存放所有对象实例和数组);
 
  程序计数器(Program Counter Register):
 
  每一个Java线程都有一个程序计数器来用于保存程序执行到当前方法的哪一个指令,对于非Native方法,这个区域记录的是正在执行的VM原语的地址,如果正在执行的是Natvie方法,这个区域则为空(undefined)。此内存区域是唯一一个在VM Spec中没有规定任何OutOfMemoryError情况的区域。
 
  Java虚拟机栈:
 
  本地变量表存放了编译期可知的各种标量类型(boolean、byte、char、short、int、float、long、double)、对象引用(不是对象本身,仅仅是一个引用指针)、方法返回地址等。其中long和double会占用2个本地变量空间(32bit),其余占用1个。
 
  本地方法栈:
 
  本地方法栈是为虚拟机使用到的Native方法服务。
 
  堆:
 
  绝大部分的对象实例和数组都在这里分配。
 
  2)开始说说分代GC,这时就把GC算法引入进来,再结合每个区域的特点把Minor GC和Full GC引入进来
 
  标记-清除算法:从根节点开始标记所有可达对象,其余没标记的即为垃圾对象,执行清除。但回收后的空间是不连续的。
 
  复制算法:将内存分成两块,每次只使用其中一块,垃圾回收时,将标记的对象拷贝到另外一块中,然后完全清除原来使用的那块内存。复制后的空间是连续的。(适用于新生代)
 
  标记-压缩算法:适合用于老年代的算法(存活对象多于垃圾对象)。标记后不复制,而是将存活对象压缩到内存的一端,然后清理边界外的所有对象。
 
  2)可以跟他说说垃圾回收器,Serial、ParNew、CMS等等
 
  Serial是单线程的,新生代使用的是复制算法,老年代使用的是标记整理算法;
 
  ParNew是Serial的多线程版本,Parallel Scavenge是ParNew的增强版,提供可控制的吞吐量设置;
 
  Serial Old和ParNew Old对应的是老年代的GC;
 
  CMS是一种以获取最短回收停顿时间为目标的收集器;使用的标记清楚算法;
 
  初始标记,并发标记,重新标记,并发清除;
 
  21.垃圾回收器G1,我只说了CMS
 
  CMS包含初始标记、并发标记、重新标记、并发清除4步。其中初始标记和重新标记是需要停止其他操作的,并发标记和并发清除是与应用线程并发执行。
 
  但是CMS是CPU资源敏感的;无法处理浮动垃圾;CMS是基于“标记-清除”算法的,所以有碎片。
 
  G1是面向服务端的,特点:并行与并发、分代收集、空间整合(使用标记-整理算法)、可预测停顿。它不再区分新老生代,而是划分region,并通过Remembered Set来避免全堆扫描。
 
  G1收集过程是:初始标记、并发标记、最终标记和筛选回收。除了并发标记是并发的,其他都是阻塞的。
 
  6.说说死锁吧,怎么检测死锁?
 
  死锁:是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。
 
  四个条件同时具备:互斥条件、不可抢占条件、占有且申请条件、循环等待条件。
 
  避免方法:
 
  (1)严格按照一定顺序访问资源;
 
  (2)在取得进程能够执行的所有资源后才给进程分配资源,否则不分配;
 
  (3)
 
  银行家算法:
 
  7.说一说ThreadLocal关键字吧,答出核心。还有volatile,synchronized,Lock
 
  当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
 
  安全:使用元子类,实现并发锁,使用线程安全的类,使用volatile关键字,
 
  8.聚簇索引和非聚簇索引的区别。下面贴一下核心内容:
 
  建立聚族索引:CREATE CLUSTER INDEX index_name ON table_name(column_name1,column_name2,...);
 
  存储特点:
 
  聚集索引:表数据按照索引的顺序来存储的,也就是说索引项的顺序与表中记录的物理顺序一致。对于聚集索引,叶子结点即存储了真实的数据行,不再有另外单独的数据页。在一张表上最多只能创建一个聚集索引,因为真实数据的物理顺序只能有一种。
 
  非聚集索引:表数据存储顺序与索引顺序无关。对于非聚集索引,叶结点包含索引字段值及指向数据页数据行的逻辑指针,其行数量与数据表行数据量一致。
 
  9.说一说项目中Spring的IOC和AOP具体怎么使用的。
 
  几乎都用的IOC(通过Spring容器进行对象的管理,以及对象之间组合关系的映射)
 
  日志管理是AOP
 
  10.谈一谈对数据库事务的理解。四个特性和隔离级别必须要牢记,了解
 
  事务并发控制带来的问题:脏读、不可重复读、更新丢失、幻读等等
 
  原子性,一致性,隔离性,持久性;
 
  ①Serializable(串行化):可避免脏读、不可重复读、幻读的发生。
 
  ②Repeatable read(可重复读):可避免脏读、不可重复读的发生。
 
  ③Read committed(读已提交):可避免脏读的发生。
 
  ④Read uncommitted(读未提交):最低级别,任何情况都无法保证。
 
  MySql在哪一个级别?
 
  4种都有啊?
 
  11.问我Hibernate的生成策略,主要说了native、uuid
 
  12.说说struts,我就拿出struts 1和struts 2对比着说了
 
  13.mysql熟悉吗?知道间隙锁吗?InnodB,MyISAM区别?
 
  http://blog.csdn.net/d12345678a/article/details/53858117
 
  当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但并不存在的记录,叫做“间隙(GAP)”,InnoDB也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁(Next-Key锁)。InnoDB除了通过范围条件加锁时使用间隙锁外,如果使用相等条件请求给一个不存在的记录加锁,InnoDB也会使用间隙锁!
 
  Select*from emp where empid>100 for update;
 
  间隙锁的主要作用是为了防止出现幻读,但是它会把锁定范围扩大,有时候也会给我们带来麻烦。
 
  间隙锁,然后数据库会向左扫描扫到第一个比给定参数小的值,向右扫描扫描到第一个比给定参数大的值,然后以此为界,构建一个区间,锁住整个区间内的数据。
 
  InnoDB存储引擎既支持行级锁(row-level locking),也支持表级锁,但默认情况下是采用行级锁。MyISAM存储引擎只支持表锁。
 
  MyISAM表锁是deadlock free的,这是因为MyISAM总是一次获得所需的全部锁,要么全部满足,要么等待,因此不会出现死锁。
 
  表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
 
  行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
 
  MySQL的表级锁有两种模式:表共享读锁(Table Read Lock)和表独占写锁(Table Write Lock)。MyISAM在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,在执行更新操作(UPDATE、DELETE、INSERT等)前,会自动给涉及的表加写锁,这个过程并不需要用户干预,因此,用户一般不需要直接用LOCK TABLE命令给MyISAM表显式加锁。
 
  例子:
 
  Lock tables orders read local,order_detail read local;
 
  Select sum(total)from orders;
 
  Select sum(subtotal)from order_detail;
 
  Unlock tables;
 
  上面的例子在LOCK TABLES时加了“local”选项,其作用就是在满足MyISAM表并发插入条件的情况下,允许其他用户在表尾并发插入记录。MyISAM是写优先的。
 
  通过定期在系统空闲时段执行OPTIMIZE TABLE语句来整理空间碎片,收回因删除记录而产生的中间空洞。
 
  InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION);二是采用了行级锁。
 
  l共享锁(S):允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。
 
  l排他锁(X):允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的共享读锁和排他写锁。
 
  另外,为了允许行锁和表锁共存,实现多粒度锁机制,InnoDB还有两种内部使用的意向锁(Intention Locks),这两种意向锁都是表锁。
 
  l意向共享锁(IS):事务打算给数据行加行共享锁,事务在给一个数据行加共享锁前必须先取得该表的IS锁。
 
  l意向排他锁(IX):事务打算给数据行加行排他锁,事务在给一个数据行加排他锁前必须先取得该表的IX锁。
 
  共享锁(S):SELECT*FROM table_name WHERE...LOCK IN SHARE MODE。
 
  排他锁(X):SELECT*FROM table_name WHERE...FOR UPDATE。
 
  InnoDB行锁是通过给索引上的索引项加锁来实现的.由于MySQL的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但是如果是使用相同的索引键,是会出现锁冲突的。如果不是相同的索引就不会等待。
 
  create table tab_no_index(id int,name varchar(10))engine=innodb;
 
  一是MySQL的恢复是SQL语句级的,也就是重新执行BINLOG中的SQL语句。
 
  二是MySQL的Binlog是按照事务提交的先后顺序记录的,恢复也是按这个顺序进行的。
 
  14.java的优势
 
  简单(GC)、面向对象、平台无关(JVM)、分布式、多线程、可靠和安全等特性
 
  15.有没有用过哪些集合?
 
  Collection接口的接口对象的集合
 
  ├List子接口按进入先后有序保存可重复
 
  │├LinkedList接口实现类链表插入删除没有同步线程不安全
 
  │├ArrayList接口实现类数组随机访问没有同步线程不安全
 
  │└Vector接口实现类数组同步线程安全
 
  │└Stack
 
  ├Queue子接口队列集合
 
  └Set子接口仅接收一次,并做内部排序
 
  ├HashSet
 
  │└LinkedHashSet插入的次序
 
  └TreeSet
 
  Map接口键值对的集合
 
  ├Hashtable接口实现类同步线程安全键值非空
 
  ├HashMap接口实现类没有同步线程不安全
 
  │├LinkedHashMap插入次序
 
  │└WeakHashMap
 
  ├TreeMap基于红黑树,可以返回子树排序的
 
  └IdentifyHashMap
 
  Collections是针对集合类的一个帮助类。提供了一系列静态方法实现对各种集合的搜索、排序、线程完全化等操作。相当于对Array进行类似操作的类——Arrays。
 
  16.Arraylist如何实现排序
 
  使用Collections.sort()传入ArrayList,会采用默认的方式进行排序(字典序)
 
  使用Collections.sort()传入ArrayList和自己实现Commparator接口的类的对象,实现自定义排序
 
  使用List.sort()传入自己实现Commparator接口的类的对象,实现自定义排序
 
  17.Spring的annotation(注解)如何实现
 
  Annotation是代码里的特殊标记,这些标记可以在编译、类加载、运行时被读取,并执行相应的处理。通过使用Annotation,开发人员可以在不改变原有逻辑的情况下,在源文件中嵌入一些补充的信息。代码分析工具、开发工具和部署工具可以通过这些补充信息进行验证、处理或者进行部署。
 
  4个元注解:1. Target,用于描述注解的使用范围, Target(ElementType.FIELD)
 
  2. Retention,用于描述注解的生命周期, Retention(RetentionPolicy.RUNTIME)
 
  3. Documented,可以被例如javadoc此类的工具文档化
 
  4. Inherited, Inherited annotation类型是被标注过的class的子类所继承。类并不从它所实现的接口继承annotation,方法并不从它所重载的方法继承annotation。
 
  三种标准annontation类型:
 
  (1)Override,被标注的方法重载了父类的方法;
 
  (2)Deprecated
 
  (3)SuppressWarnings,此注解能告诉Java编译器关闭对类、方法及成员变量的警告。
 
   Autowired顾名思义,就是自动装配,其作用是为了消除代码Java代码里面的getter/setter与bean属性中的property。
 
  如果容器中有一个以上匹配的Bean,则可以通过 Qualifier注解限定Bean的名称;
 
   Service对应的是业务层Bean;
 
   Repository对应数据访问层Bean;
 
   Configuration把一个类作为一个IoC容器,它的某个方法头上如果注册了 Bean,就会作为这个Spring容器中的Bean。
 
   Scope注解作用域
 
   Lazy(true)表示延迟初始化
 
   Service用于标注业务层组件、
 
   Controller用于标注控制层组件(如struts中的action)
 
   Repository用于标注数据访问组件,即DAO组件。
 
   Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
 
   Scope用于指定scope作用域的(用在类上)
 
   PostConstruct用于指定初始化方法(用在方法上)
 
   PreDestory用于指定销毁方法(用在方法上)
 
   DependsOn:定义Bean初始化及销毁时的顺序
 
   Primary:自动装配时当出现多个Bean候选者时,被注解为 Primary的Bean将作为首选者,否则将抛出异常
 
   Autowired默认按类型装配,如果我们想使用按名称装配,可以结合 Qualifier注解一起使用。如下:
 
   Autowired Qualifier("personDaoBean")存在多个实例配合使用
 
   Resource默认按名称装配,当找不到与名称匹配的bean才会按类型装配。
 
   PostConstruct初始化注解
 
   PreDestroy摧毁注解默认单例启动就加载
 
   Async异步方法调用
 
  Restful的优势:
 
  透明性,暴露资源存在。
 
  充分利用HTTP协议本身语义。
 
  无状态,这点非常重要。在调用一个接口(访问、操作资源)的时候,可以不用考虑上下文,不用考虑当前状态,极大的降低了复杂度
 
  HTTP本身提供了丰富的内容协商手段,无论是缓存,还是资源修改的乐观并发控制,都可以以业务无关的中间件来实现
 
  低耦合;
 
  18.Redis如何解决key冲突
 
  19.HashMap,ConcurrentHashMap以及在什么情况下性能会不好
 
  HashMap不是线程安全的
 
  23.Java中的HashMap的工作原理是什么?
 
  Java中的HashMap是以键值对(key-value)的形式存储元素的。HashMap需要一个hash函数,它使用hashCode()和equals()方法来向集合/从集合添加和检索元素。当调用put()方法的时候,HashMap会计算key的hash值,然后把键值对存储在集合中合适的索引上。如果key已经存在了,value会被更新成新值。HashMap的一些重要的特性是它的容量(capacity),负载因子(load factor)和扩容极限(threshold
 
  resizing)。
 
  24.hashCode()和equals()方法的重要性体现在什么地方?
 
  equals一般是用来实现两个对象内容的比较,如果不重写就会和==一样。一般重写equals方法的时候都会相应的重写hashCode方法。(重写hashCode方法是个难点)
 
  Java中的HashMap使用hashCode()和equals()方法来确定键值对的索引,当根据键获取值的时候也会用到这两个方法。如果没有正确的实现这两个方法,两个不同的键可能会有相同的hash值,因此,可能会被集合认为是相等的。而且,这两个方法也用来发现重复元素。所以这两个方法的实现对HashMap的精确性和正确性是至关重要的。
 
  如何保证key的唯一性?即hashCode和equals的实现原理
 
  相等的对象必须具有相同的散列码,但散列码相同则不一定是相等的对象,而且不相等的对象也不一定需要有不同的散列码。
 
  25.HashMap和Hashtable有什么区别?
 
  HashMap和Hashtable都实现了Map接口,因此很多特性非常相似。但是,他们有以下不同点:
 
  HashMap允许键和值是null,而Hashtable不允许键或者值是null。
 
  Hashtable是同步的,而HashMap不是。因此,HashMap更适合于单线程环境,而Hashtable适合于多线程环境。
 
  HashMap提供了可供应用迭代的键的集合,因此,HashMap是快速失败的。另一方面Hashtable提供了对键的列举(Enumeration)。一般认为Hashtable是一个遗留的类。
 
  20.Synchronized和lock区别
 
  wait()和notify()必须在synchronized代码块中调用。
 
  在并发量比较小的情况下,使用synchronized是个不错的选择,但是在并发量比较高的情况下,其性能下降很严重,此时ReentrantLock是个不错的方案。
 
  区别:
 
  (1)Synchronized是java关键字,是内置特性;而Lock是一个类;
 
  (2)Lock可以让等待锁的线程响应中断,而synchronized却不行;
 
  (3)Lock可以提高多个线程进行读操作的效率;
 
  (4)Synchronized的锁是自动释放的,Lock需要手动释放;
 
  (5)Lock可以知道线程有没有成功获得锁。
 
  java.util.concurrent.locks有Lock是一个接口:
 
  void lock();
 
  void lockInterruptibly()throws InterruptedException;
 
  boolean tryLock();
 
  boolean tryLock(long time,
 
  TimeUnit unit)throws InterruptedException;
 
  void unlock();
 
  ReentrantLock(可重入锁)是唯一实现了Lock接口的类。
 
  单独调用interrupt()方法不能中断正在运行过程中的线程,只能中断阻塞过程中的线程。
 
  ReentrantReadWriteLock是唯一实现ReadWriteLock接口的类,有ReadLock和WriteLock方法。
 
  synchronized和ReentrantLock都是可重入锁。
 
  公平锁即尽量以请求锁的顺序来获取锁。比如同是有多个线程在等待一个锁,当这个锁被释放时,等待时间最久的线程(最先请求的线程)会获得该所,这种就是公平锁。
 
  ReentrantLock lock=new ReentrantLock(true);
 
  ,synchronized就是非公平锁,它无法保证等待的线程获取锁的顺序。
 
  而对于ReentrantLock和ReentrantReadWriteLock,它默认情况下是非公平锁,但是可以设置为公平锁。
 
  public void test(){
 
  ...
 
  synchronized(this){
 
  //todo your code
 
  }
 
  ...
 
  }
 
  此时,其效果等同于
 
  public synchronized void test(){
 
  //todo your code
 
  }
 
  22.一般线程和守护线程的区别
 
  Daemon的作用是为其他线程的运行提供服务,比如说GC线程。thread.setDaemon(true)必须在thread.start()之前设置。在Daemon线程中产生的新线程也是Daemon的。
 
  当所有的非守护线程结束时,程序也就终止了,同时会杀死进程中的所有守护线程
 
  24.JDK中哪些体现了命令模式
 
  命令模式:将一个请求封装为一个对象,从而让我们可用不同的请求对客户进行参数化,用于“行为请求者”与“行为实现者”解耦,可实现二者之间的松耦合,以便适应变化。命令模式是一种对象行为型模式,其别名为动作(Action)模式或事务(Transaction)模式。
 
  java.lang.Runnable和javax.swing.Action是使用命令模式的经典场景。
 
  25.简单介绍下线程池的参数?你了解哪些线程池?线程池使用了什么设计模式?线程池使用时一般要考虑哪些问题?
 
  java.util.concurrent.ThreadPoolExecutor;
 
  corePoolSize:核心池的大小
 
  maximumPoolSize:线程池最大线程数
 
  keepAliveTime:表示线程没有任务执行时最多保持多久时间会终止。
 
  threadFactory:线程工厂,主要用来创建线程;
 
  handler:表示当拒绝处理任务时的策略,有以下四种取值:
 
  ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
 
  ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
 
  ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
 
  ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务
 
  线程池状态:
 
  static
 
  final int
 
  RUNNING=0;
 
  static
 
  final int
 
  SHUTDOWN=1;
 
  static
 
  final int
 
  STOP=2;
 
  static
 
  final int
 
  TERMINATED=3;
 
  execute()
 
  submit()
 
  shutdown()
 
  shutdownNow()立即终止线程池,并尝试打断正在执行的任务,并且清空任务缓存队列,返回尚未执行的任务.
 
  线程池的种类:
 
  Executors.newCachedThreadPool();//创建一个缓冲池,缓冲池容量大小为Integer.MAX_VALUE
 
  Executors.newSingleThreadExecutor();//创建容量为1的缓冲池
 
  Executors.newFixedThreadPool(int);//创建固定容量大小的缓冲池
 
  Executors.newScheduleThreadPool创建一个定长的线程池,而且支持定时的以及周期性的任务执行,类似于Timer。
 
  一般需要根据任务的类型来配置线程池大小:
 
  如果是CPU密集型任务,就需要尽量压榨CPU,参考值可以设为NCPU+1
 
  如果是IO密集型任务,参考值可以设置为2*NCPU
 
  单个任务处理的时间很短而请求的数目却是巨大的。join和close都可以用来关闭线程池。不同的是,join会把队列中的任务执行完,而close则立刻清空队列,并且中断所有的工作线程。
 
  线程池大小,死锁,系统资源不足,并发错误,线程泄漏(比如都在等待用户输入),任务过载(太多等待任务)。
 
  26.一致性Hash原理
 
  27.Java虚拟机的一些参数配置
 
  Trace跟踪参数:
 
  -XX:+PrintGCDetails打印GC详细信息;
 
  -XX:+PrintGCTimeStamps打印GC时间戳;
 
  -Xloggc:log/gc.log指定GC log的位置;
 
  -XX:+PrintHeapAtGC每一次GC前和GC后,都打印堆信息;
 
  -XX:+TraceClassLoading监控类的加载;
 
  -XX:+PrintClassHistogram按下Ctrl+Break后,打印类的信息;
 
  堆的分配参数:
 
  -Xmx20m-Xms5m指定最大堆和最小堆;
 
  问题1:-Xmx(最大堆空间)和–Xms(最小堆空间)应该保持一个什么关系,可以让系统的性能尽可能的好呢?
 
  问题2:如果你要做一个Java的桌面产品,需要绑定JRE,但是JRE又很大,你如何做一下JRE的瘦身呢?
 
  -Xmn官方推荐新生代占堆的3/8,幸存代占新生代的1/10
 
  设置新生代大小
 
  -XX:NewRatio=4
 
  新生代(eden+2*s)和老年代(不包含永久区)的比值
 
  例如:4,表示新生代:老年代=1:4,即新生代占整个堆的1/5
 
  -XX:SurvivorRatio=2(幸存代)
 
  设置两个Survivor区和eden的比值
 
  例如:8,表示两个Survivor:eden=2:8,即一个Survivor占年轻代的1/10
 
  -XX:+HeapDumpOnOutOfMemoryError-XX:HeapDumpPath=d:/a.dump
 
  如果发生了OOM异常,那就把dump信息导出到d:/a.dump文件中。
 
  -XX:OnOutOfMemoryError=D:/tools/jdk1.7_40/bin/printstack.bat%p//p代表的是当前进程的pid
 
  上方参数的意思是说,执行printstack.bat脚本,而这个脚本做的事情是:D:/tools/jdk1.7_40/bin/jstack-F%1>D:/a.txt,即当程序OOM时,在D:/a.txt中将会生成线程的dump。
 
  -XX:PermSize=16m-XX:MaxPermSize:设置永久区的初始空间和最大空间;
 
  栈的分配参数:
 
  Xss设置栈空间的大小。通常只有几百K;-Xss128K
 
  -XX:+UseParallelGC-XX:ParallelGCThreads=20此配置仅对年轻代有效。
 
  -XX:MaxGCPauseMillis=100:设置每次年轻代垃圾回收的最长时间
 
  -XX:+UseCMSCompactAtFullCollection:打开对年老代的压缩。
 
  常见配置汇总
 
  堆设置
 
  -Xms:初始堆大小
 
  -Xmx:最大堆大小
 
  -XX:NewSize=n:设置年轻代大小
 
  -XX:NewRatio=n:设置年轻代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4
 
  -XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5
 
  -XX:MaxPermSize=n:设置持久代大小
 
  收集器设置
 
  -XX:+UseSerialGC:设置串行收集器
 
  -XX:+UseParallelGC:设置并行收集器
 
  -XX:+UseParalledlOldGC:设置并行年老代收集器
 
  -XX:+UseConcMarkSweepGC:设置并发收集器
 
  垃圾回收统计信息
 
  -XX:+PrintGC
 
  -XX:+PrintGCDetails
 
  -XX:+PrintGCTimeStamps
 
  -Xloggc:filename
 
  并行收集器设置
 
  -XX:ParallelGCThreads=n:设置并行收集器收集时使用的CPU数。并行收集线程数。
 
  -XX:MaxGCPauseMillis=n:设置并行收集最大暂停时间
 
  -XX:GCTimeRatio=n:设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)
 
  并发收集器设置
 
  -XX:+CMSIncrementalMode:设置为增量模式。适用于单CPU情况。
 
  -XX:ParallelGCThreads=n:设置并发收集器年轻代收集方式为并行收集时,使用的CPU数。并行收集线程数。
 
  28.Raft协议的leader选举,正常情况下,网络抖动造成follower发起leader选举,且该follower的
 
  Term比现有leader高。集群中所有结点的日志信息当前一致,这种情况下会选举成功吗?
 
  只要term加1之后,之前的leader就作废,这轮选举一定能选出来。我觉得还得看下这个term什么时候会加1,意思就是题目中follower在什么情况下term比之前leader高。因为follower在一个时间段内因为网络波动收不到leader的心跳,他就自动转化为candidate状态且term+1。
 
  29.Tcp连接4次挥手的原因。Time_wait等待超时了会怎样?
 
  time_wait状态本来就是等待2个msl就直接进入closed状态
 
  TIME_WAIT状态维持时间是两个MSL时间长度,也就是在1-4分钟。Windows操作系统就是4分钟。
 
  MSL就是maximum segment lifetime(最大分节生命期),这是一个IP数据包能在互联网上生存的最长时间.
 
  time_wait存在的原因:
 
  1.可靠的终止TCP连接。
 
  2.保证让迟来的TCP报文段有足够的时间被识别并丢弃。
 
  为什么要三次握手:
 
  为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。
 
  “已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。
 
  为什么需要四次挥手:
 
  原因是因为tcp是全双工模式,接收到FIN时意味将没有数据再发来,但是还是可以继续发送数据。
 
  30.不同进程打开了同一个文件,那么这两个进程得到的文件描述符(fd)相同吗?
 
  31.给定一个2叉树,打印每一层最右边的结点
 
  32.spring bean初始化过程,Spring的DI工作原理,spring bean生命周期:
 
  1.容器寻找Bean的定义信息并且将其实例化。
 
  2.受用依赖注入,Spring按照Bean定义信息配置Bean的所有属性。
 
  3.如果Bean实现了BeanNameAware接口,工厂调用Bean的setBeanName()方法传递Bean的ID。
 
  4.如果Bean实现了BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身。
 
  5.如果BeanPostProcessor和Bean关联,那么它们的postProcessBeforeInitialzation()方法将被调用。
 
  6.如果Bean指定了init-method方法,它将被调用。
 
  7.最后,如果有BeanPsotProcessor和Bean关联,那么它们的postProcessAfterInitialization()方法将被调用。
 
  生命周期:执行完上面的步骤就可以使用了,使用完毕后关闭容器:
 
  调用DisposableBean的destory方法;
 
  Bean在实例化的过程中:Constructor> PostConstruct>InitializingBean>init-method
 
  Bean在销毁的过程中: PreDestroy>DisposableBean>destroy-method
 
  33.说一说对java io的理解
 
  在整个Java.io包中最重要的就是5个类和一个接口。5个类指的是File、OutputStream、InputStream、Writer、Reader;一个接口指的是Serializable.
 
  适配器模式,改变接口来重复使用
 
  把一个类的接口变成客户端能接受的另一种接口。
 
  使两个接口不一样的类能一起工作。
 
  InputStreamReader适配器实现了Reader接口,持有InputStream引用。这样Reader字节最终调用InputStream
 
  InputStreamReader:对象+接口
 
  装饰器模式,接口不变,增强原来对象的功能
 
  赋予类更多的功能,
 
  FileInputStream,
 
  BufferedInputStream是具体实现者,把InputStream读取内容保存在内存中,增强了功能。
 
  34.juc包(Java.util.concurrent)内有哪些类,CAS(比较并交换(compare
 
  and swap))如何实现,说一下对线程池的理解
 
  它的基础就是AbstractQueuedSynchronizer抽象类,Lock,CountDownLatch等的基础就是该类,而该类又用到了CAS操作。CAS之前已经介绍过。JUC在同步器的设计上有获取操作和释放操作。AbstractQueuedSynchronizer(AQS)就是一种同步器的实现。
 
  原子对象;
 
  locks;
 
  Semaphore一个计数信号量,主要用于控制多线程对共同资源库访问的限制。
 
  CountDownLatch一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。CyclicBarrier用于一组线程执行时,每个线程执行有多个节点,每个节点的处理需要相互等待。
 
  CAS操作包含三个操作数——内存位置(V)、预期原值(A)和新值(B)。我认为位置V应该包含值A;如果包含该值,则将B放到这个位置;否则,不要更改该位置,只告诉我这个位置现在的值即可。但是有ABA的问题,可以通过版本号来解决。
 
  public synchronized int compareAndSwap(int expectedValue,int newValue){
 
  int oldValue=value;
 
  if(oldValue==expectedValue){
 
  value=newValue;
 
  }
 
  return oldValue;
 
  }
 
  unsafe.compareAndSwapInt(this,valueOffset,expect,update);
 
  36.树的中序遍历,除了递归和栈还有什么实现方式
 
  Morris遍历,实际上是用叶子节点的空指针来记录当前节点的位置,然后一旦遍历到了叶子节点,发现叶子节点的右指针指向的是当前节点,那么就认为以当前节点的左子树已经遍历完成。
 
  它的遍历规则如下:
 
  1.如果当前节点的左子节点为空时,输出当前节点,并将当前节点置为该节点的右子节点;
 
  2.如果当前节点的左子节点不为空,找到当前节点左子树的最右节点(该节点为当前节点中序遍历的前驱节点);
 
  2.1.如果最右节点的右指针为空(right=null),将最右节点的右指针指向当前节点,当前节点置为其左子节点;
 
  2.2.如果最右节点的右指针不为空,将最右节点右指针重新置为空(恢复树的原状),输出当前节点,并将当前节点置为其右节点;
 
  3.重复1~2,直到当前节点为空。
 
  37.操作系统如何实现输出
 
  38.说一下对B+树的了解
 
  39.linux查询java进程
 
  ps-ef|grep java
 
  kill-9[PID]-9表示强迫进程立即停止
 
  40.linux查看内存占用情况
 
  cat
 
  /proc/meminfo
 
  sudo atop atop命令是一个终端环境的监控命令。它显示的是各种系统资源的综合,并且在高负载的情况下进行了彩色标注。
 
  top top命令提供了实时的运行中的程序的资源使用统计。
 
  free-h free命令是一个快速查看内存使用情况的方法,它是对/proc/meminfo收集到的信息的一个概述。
 
  ps命令可以实时的显示各个进程的内存使用情况。
 
  vmstat命令显示实时的和平均的统计,覆盖CPU、内存、I/O等内容。
 
  41.String,是否可以继承,“+”怎样实现,与StringBuffer,StringBuilder区别
 
  因为有final关键字,所以不能被继承。
 
  “+”是通过StringBuffer或者是StringBuilder的append()和toString()方法来实现的。
 
  String类对象为不可变对象,StringBuffer类对象为可修改对象,可以通过append()方法来修改值;都是线程安全的。
 
  StringBuilder线程不安全,但是效率比StringBuffer高。
 
  42.map源码,怎样解决冲突,和扩容
 
  开放地址法是对那些发生冲突的记录,用hi=(h(key)+di)mod n方法再次确定Hash地址。
 
  n:为哈希表长;
 
  di:为增量序列,其取法有以下三种:
 
  1)线性探测再散列di=c*i
 
  2)二次探测再散列di=12,-12,22,-22,…,
 
  3)随机探测再散列di是一组伪随机数列或者di=i×H2(key)(又称双散列函数探测)
 
  链地址法:将所有哈希地址相同的记录都链接在同一链表中
 
  43.servlet流程
 
  Web Client向Servlet容器(Tomcat)发出Http请求
 
  Servlet容器接收Web Client的请求
 
  Servlet容器创建一个HttpRequest对象,将Web Client请求的信息封装到这个对象中。
 
  Servlet容器创建一个HttpResponse对象
 
  Servlet容器调用HttpServlet对象的service方法,把HttpRequest对象与HttpResponse对象作为参数传给HttpServlet对象。
 
  HttpServlet调用HttpRequest对象的有关方法,获取Http请求信息。
 
  HttpServlet调用HttpResponse对象的有关方法,生成响应数据。
 
  Servlet容器把HttpServlet的响应结果传给Web Client。
 
  44.异常:Java中的两种异常类型是什么?他们有什么区别?
 
  Java异常分为Exception和Error两大类型,Exception又分为运行时异常(RuntimeException)和非运行时异常(如IOException),运行时异常代表运行时由Java虚拟机生成的异常,Java编译器要求Java程序必须捕获或生命所有的非运行时异常,但对运行时异常可以不做处理。
 
  Java中有两种异常:受检查的(checked)异常和不受检查的(unchecked)异常。不受检查的异常不需要在方法或者是构造函数上声明,就算方法或者是构造函数的执行可能会抛出这样的异常,并且不受检查的异常可以传播到方法或者是构造函数的外面。相反,受检查的异常必须要用throws语句在方法或者是构造函数上声明。这里有Java异常处理的一些小建议。
 
  Java中Exception和Error有什么区别?
 
  方法运行过程中如果发生了意外,方法将生成一个相应类型的异常,并把它交给运行时系统,这一过程称为抛出。运行时系统受到异常后,会寻找相应的代码来处理,这一过程称为捕获。
 
  Exception和Error都是Throwable的子类。Exception用于用户程序可以捕获的异常情况。Error是指Java虚拟机内部发生错误,由虚拟机生产并抛出,定义了不期望被用户程序捕获的异常。
 
  Java的异常处理方式有两种:(1)try-catch-finally;(2)throws。
 
  为什么使用自定义异常?
 
  因为项目中有时会有符合Java语法,但是不符合业务逻辑的情况,这时就需要自定义异常了。
 
  45.序列化,以及json传输
 
  47.tomcat均衡方式,netty
 
  48.session/cookie
 
  什么是cookie?session和cookie有什么区别?
 
  cookie是Web服务器发送给浏览器的一块信息。浏览器会在本地文件中给每一个Web服务器存储cookie。以后浏览器在给特定的Web服务器发请求的时候,同时会发送所有为该服务器存储的cookie。下面列出了session和cookie的区别:
 
  无论客户端浏览器做怎么样的设置,session都应该能正常工作。客户端可以选择禁用cookie,但是,session仍然是能够工作的,因为客户端无法禁用服务端的session。
 
  在存储的数据量方面session和cookies也是不一样的。session能够存储任意的Java对象,cookie只能存储String类型的对象。
 
  设置session有效期的方法有:
 
  (1)在Tomcat的server.xml中定义;
 
  (2)在工程的web.xml中定义;
 
  (3)通过session.setMaxInactiveInterval(1000);
 
  判断session是否失效:
 
  request.getSession(false)==null?
 
  清楚session中的信息:session.invalidate();
 
  Cookie可以设置有效期:cookie.setMaxAge(120);
 
  在禁用Cookie的情况下使用Session:response.encodeurl(url);
 
  49.利用数组,实现一个循环队列类
 
  队为空的判断:front==rear;队为满的判断:(rear+1)%MAXSIZE==front。
 
  public class CircleQueue{
 
  private int[]q=null;
 
  //首索引
 
  private int head=0;
 
  //尾索引
 
  private int tail=0;
 
  private int len=0;
 
  public CircleQueue(int len){
 
  this.len=len;
 
  q=new int[len];
 
  }
 
  //insert into circle queue
 
  private int insert(int x){
 
  //判断循环队列是否已满
 
  if(isFull()){
 
  System.out.println("circle queue is Full");
 
  return-1;
 
  }else{
 
  q[tail]=x;
 
  //逻辑上实现首尾相连,循环队列
 
  tail=(tail+1)%len;
 
  //返回最近插入的元素
 
  return x;
 
  }
 
  }
 
  private int pop(){
 
  if(isNull()){
 
  System.out.println("circle queue is Null");
 
  return-1;
 
  }else{
 
  int n=q[head];
 
  //头结点不断追赶尾结点
 
  head=(head+1)%len;
 
  //返回最近弹出的元素
 
  return n;
 
  }
 
  }
 
  private int head(){
 
  return q[head];
 
  }
 
  private int tail(){
 
  return q[(tail+len-1)%len];
 
  }
 
  private boolean isFull(){
 
  if((tail+1)%len==head){
 
  return true;
 
  }else{
 
  return false;
 
  }
 
  }
 
  //check is null
 
  private boolean isNull(){
 
  //首尾相等的话则为空
 
  if(head==tail){
 
  return true;
 
  }else{
 
  return false;
 
  }
 
  }
 
  }
 
  50.http头,TCP/IP有几层,每层有何含义
 
  GET http://download.microtool.de:80/somedata.exe
 
  Host:download.microtool.de
 
  Accept:*/*告诉WEB服务器自己接受什么介质类型,*/*表示任何类型
 
  Pragma:no-cache
 
  Cache-Control:no-cache指定请求和响应遵循的缓存机制。
 
  Connection:Keep-Alive表示连接状态
 
  Referer:http://download.microtool.de/
 
  User-Agent:Mozilla/4.04[en](Win95;I;Nav)
 
  Range:bytes=554554-
 
  响应:
 
  HTTP/1.0 200 OK
 
  Date:Mon,31Dec200104:25:57GMT
 
  Server:Apache/1.3.14(Unix)
 
  Content-type:text/html
 
  Last-modified:Tue,17Apr200106:46:28GMT
 
  Etag:"a030f020ac7c01:1e9f"
 
  Content-length:39725426
 
  Content-range:bytes554554-40279979/40279980
 
  TCP/IP的4层模型:
 
  (1)应用层:FTP、DNS、Telnet、SMTP、HTTP
 
  (2)传输层:TCP(传输控制协议)、UDP(用户数据报协议)
 
  (3)网络层:IP
 
  (4)网络接口层:接受和发送IP数据包。
 
  51.DNS的解析流程
 
  1、在浏览器中输入www.qq.com域名,操作系统会先检查自己本地的hosts文件是否有这个网址映射关系,如果有,就先调用这个IP地址映射,完成域名解析。
 
  2、如果hosts里没有这个域名的映射,则查找本地DNS解析器缓存,是否有这个网址映射关系,如果有,直接返回,完成域名解析。
 
  3、如果hosts与本地DNS解析器缓存都没有相应的网址映射关系,首先会找TCP/ip参数中设置的首选DNS服务器,在此我们叫它本地DNS服务器,此服务器收到查询时,如果要查询的域名,包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析,此解析具有权威性。
 
  4、如果要查询的域名,不由本地DNS服务器区域解析,但该服务器已缓存了此网址映射关系,则调用这个IP地址映射,完成域名解析,此解析不具有权威性。
 
  5、如果本地DNS服务器本地区域文件与缓存解析都失效,则根据本地DNS服务器的设置(是否设置转发器)进行查询,如果未用转发模式,本地DNS就把请求发至13台根DNS,根DNS服务器收到请求后会判断这个域名(.com)是谁来授权管理,并会返回一个负责该顶级域名服务器的一个IP。本地DNS服务器收到IP信息后,将会联系负责.com域的这台服务器。这台负责.com域的服务器收到请求后,如果自己无法解析,它就会找一个管理.com域的下一级DNS服务器地址
 
  (qq.com)给本地DNS服务器。当本地DNS服务器收到这个地址后,就会找qq.com域服务器,重复上面的动作,进行查询,直至找到www.qq.com主机。
 
  6、如果用的是转发模式,此DNS服务器就会把请求转发至上一级DNS服务器,由上一级服务器进行解析,上一级服务器如果不能解析,或找根DNS或把转请求转至上上级,以此循环。不管是本地DNS服务器用是是转发,还是根提示,最后都是把结果返回给本地DNS服务器,由此DNS服务器再返回给客户机。
 
  当应用过程需要将一个主机域名映射为IP地址时,就调用域名解析函数,解析函数将待转换的域
 
  名放在DNS请求中,以UDP报文方式发给本地域名服务器。本地的域名服务器查到域名后,将对应的IP地址放在应答报文中返回。同时域名服务器还必须具有连向其他服务器的信息以支持不能解析时的转发。若域名服务器
 
  不能回答该请求,则此域名服务器就暂成为DNS中的另一个客户,向根域名服务器发出请求解析,根域名服务器一定能找到下面的所有二级域名的域名服务器,这样以此类推,一直向下解析,直到查询到所请求的域名。
 
  52.MapReduce
 
  52.Object中的方法
 
  protected Object clone()
 
  创建并返回此对象的一个副本。
 
  boolean equals(Object obj)
 
  指示其他某个对象是否与此对象“相等”。
 
  protected void finalize()
 
  当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
 
  Class<?>getClass()
 
  返回此Object的运行时类。
 
  int hashCode()
 
  返回该对象的哈希码值。
 
  void notify()
 
  唤醒在此对象监视器上等待的单个线程。
 
  void notifyAll()
 
  唤醒在此对象监视器上等待的所有线程。
 
  String toString()
 
  返回该对象的字符串表示。
 
  void wait()
 
  在其他线程调用此对象的notify()方法或notifyAll()方法前,导致当前线程等待。
 
  void wait(long timeout)
 
  在其他线程调用此对象的notify()方法或notifyAll()方法,或者超过指定的时间量前,导致当前线程等待。
 
  void wait(long timeout,int nanos)
 
  在其他线程调用此对象的notify()方法或notifyAll()方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导致当前线程等待。
 
  54.进程和线程的区别是什么?
 
  进程是执行着的应用程序,而线程是进程内部的一个执行序列。一个进程可以有多个线程。线程又叫做轻量级进程。
 
  进程是CPU分配资源的最小单位,线程是CPU调度和程序执行的最小单位;
 
  一个进程有几个(至少一个)线程组成,他们共享进程资源,同一个人进程可以有多个线程并发,一个线程可以创建和撤销另一个线程;
 
  进程有自己的独立地址空间,线程只有自己的堆栈和局部变量;
 
  进程切换需要很大的开销,线程开销相对较小。
 
  协程避免了无意义的调度,由此可以提高性能,但也因此,程序员必须自己承担调度的责任,同时,协程也失去了标准线程使用多CPU的能力。
 
  55.java的反射机制
 
  反射的作用于原理。
 
  反射是指程序可以访问、检测和修改其自身状态或行为的一种能力。
 
  56.数据库索引的实现,MySQL主从结构
 
  数据库的DDL、DML(数据操纵语言)
 
  DDL(数据库定义语句)是SQL语言的四大功能之一。
 
  用于定义数据库的三级结构,包括外模式、概念模式、内模式及其相互之间的映像,定义数据的完整性、安全控制等约束
 
  DDL不需要commit.
 
  CREATE
 
  ALTER
 
  DROP
 
  TRUNCATE
 
  COMMENT
 
  RENAME
 
  DML分成交互型DML和嵌入型DML两类。
 
  依据语言的级别,DML又可分成过程性DML和非过程性DML两种。
 
  需要commit.
 
  SELECT
 
  INSERT
 
  UPDATE
 
  DELETE
 
  MERGE
 
  CALL
 
  EXPLAIN PLAN
 
  LOCK TABLE
 
  DCL(数据库控制语言)
 
  GRANT授权
 
  REVOKE取消授权
 
  TCL(Transaction Control Language)事务控制语言
 
  SAVEPOINT设置保存点
 
  ROLLBACK回滚
 
  SET TRANSACTION
 
  57.StringBuilder内部实现
 
  58.linux相关:查看线程命令,用户态和内核态
 
  内核态:CPU可以访问内存所有数据,包括外围设备,例如硬盘,网卡.CPU也可以将自己从一个程序切换到另一个程序
 
  用户态:只能受限的访问内存,且不允许访问外围设备.占用CPU的能力被剥夺,CPU资源可以被其他程序获取
 
  用户态程序将一些数据值放在寄存器中,或者使用参数创建一个堆栈(stack frame),以此表明需要操作系统提供的服务.
 
  用户态程序执行陷阱指令
 
  CPU切换到内核态,并跳到位于内存指定位置的指令,这些指令是操作系统的一部分,他们具有内存保护,不可被用户态程序访问
 
  这些指令称之为陷阱(trap)或者系统调用处理器(system call handler).他们会读取程序放入内存的数据参数,并执行程序请求的服务
 
  系统调用完成后,操作系统会重置CPU为用户态并返回系统调用的结果
 
  用户态切换到内核态的3种方式:a.系统调用;b.异常;c.外围设备的中断。
 
  59.Runnable传入Thread构造方法,算是什么设计模式。
 
  代理设计模式。
 
  Runnable target=new MyTarget();//目标角色
 
  Thread proxy=new Thread(target);//代理角色
 
  proxy.start();
 
  61.系统降级的方案。
 
  在开发高并发系统时有三把利器用来保护系统:缓存、降级和限流。
 
  62.socket客户端和服务端
 
  http://blog.csdn.net/zhangyiacm/article/details/49488721
 
  private void handleSocket()throws Exception{
 
  Reader reader=new InputStreamReader(socket.getInputStream());
 
  char chars[]=new char[64];
 
  int len;
 
  StringBuilder sb=new StringBuilder();
 
  String temp;
 
  int index;
 
  while((len=reader.read(chars))!=-1){
 
  temp=new String(chars,0,len);
 
  if((index=temp.indexOf("eof"))!=-1){//遇到eof时就结束接收
 
  sb.append(temp.substring(0,index));
 
  break;
 
  }
 
  sb.append(temp);
 
  }
 
  System.out.println("from client:"+sb);
 
  //读完后写一句
 
  Writer writer=new OutputStreamWriter(socket.getOutputStream());
 
  writer.write("Hello Client.");
 
  writer.flush();
 
  writer.close();
 
  reader.close();
 
  socket.close();
 
  }
 
  }
 
  ----------------------------------------------------------------更新---------------------------------------------
 
  1.数据库索引:
 
  数据库索引;(高频)
 
  CREATE CLUSTER INDEX id
 
  索引的实现通常使用B树及其变种B+树。
 
  优点:加快查询速度;
 
  缺点:占用空间,维护起来比较耗时;
 
  建议使用索引的地方:主键,外键;需要排序或者根据范围来检索的列;经常需要搜索的列;WHERE子句中的列。
 
  不创建索引的列:查询很少用到的列;只有很少数据值的列;修改性远远大于检索性的列。
 
  索引类型有:主键索引,唯一索引,聚集索引。
 
  将一个节点的大小设为等于一个页,这样每个节点只需要一次I/O就可以完全载入。B-Tree中一次检索最多需要h-1次I/O(根节点常驻内存),渐进复杂度为O(h)=O(logdN)。一般实际应用中,出度d是非常大的数字,通常超过100,因此h非常小(通常不超过3)。
 
  而红黑树这种结构,h明显要深的多。由于逻辑上很近的节点(父子)物理上可能很远,无法利用局部性,所以红黑树的I/O渐进复杂度也为O(h),效率明显比B-Tree差很多。
 
  预读的长度一般为页(page)的整倍数。页是计算机管理存储器的逻辑块,硬件及操作系统往往将主存和磁盘存储区分割为连续的大小相等的块,每个存储块称为一页(在许多操作系统中,页得大小通常为4k),主存和磁盘以页为单位交换数据。当程序要
 
  读取的数据不在主存中时,会触发一个缺页异常,此时系统会向磁盘发出读盘信号,磁盘会找到数据的起始位置并向后连续读取一页或几页载入内存中,然后异常返回,程序继续运行。
 
  索引类型(全文索引),底层实现(B+树),什么情况下索引会失效
 
  索引是对数据库表中一列或多列的值进行排序的一种结构。
 
  唯一索引、主键索引和聚集索引。
 
  MySQL目前主要有以下几种索引类型:FULLTEXT,HASH,BTREE,RTREE。
 
  FULLTEXT,即为全文索引,目前只有MyISAM引擎支持。其可以在CREATE TABLE,ALTER TABLE,CREATE INDEX使用,不过目前只有CHAR、VARCHAR,TEXT列上可以创建全文索引。
 
  HASH,hash很适合做索引,为某一列或几列建立hash索引,就会利用这一列或几列的值通过一定的算法计算出一个hash值,对应一行或几行数据。
 
  以下几种情况,将导致索引失效:
 
  如果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因);
 
  对于多列索引,不是使用的第一部分,则不会使用索引
 
  3.like查询是以%开头
 
  4.如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引
 
  5.如果mysql估计使用全表扫描要比使用索引快,则不使用索引
 
  数据库优化(索引、存储引擎、sql优化、视图)
 
  1.适当建立索引:对查询进行优化,要尽量避免全表扫描,首先应考虑在where及order by涉及的列上建立索引,但索引并不是越多越好:
 
  (1)应尽量避免在where子句中对字段进行null值判断,应尽量避免在where子句中使用!=或<>操作符,以及like"%aa",使用参数,or(如果一个字段有索引,一个字段没有索引),in和not in也要慎用,应尽量避免在where子句中对字段进行函数操作,不要在where子句中的“=”左边进行函数、算术运算或其他表达式运算,在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。
 
  2.Update语句,如果只更改1、2个字段,不要Update全部字段,否则频繁调用会引起明显的性能消耗,同时带来大量日志。
 
  3.对于多张大数据量(这里几百条就算大了)的表JOIN,要先分页再JOIN,否则逻辑读会很高,性能很差。
 
  4.select count(*)from table;这样不带任何条件的count会引起全表扫描,并且没有任何业务意义,是一定要杜绝的。
 
  5.应尽可能的避免更新clustered索引数据列,因为clustered索引数据列的顺序就是表记录的物理存储顺序,一旦该列值改变将导致整个表记录的顺序的调整,会耗费相当大的资源。
 
  6.选择适当的字段类型,特别是主键:尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型。
 
  索引的实现通常使用B树及其变种B+树。
 
  ----------------------------------------------------------------------------------------------------------------------------------------
上一篇:没有了 下一篇:Java多线程、并发及线程的基础面试题
猜你喜欢
热门排行
精彩图文
  • Java线程池的作用
    Java线程池的作用
    在程序启动的时候就创建若干线程来响应处理,它们被称为线程池,里面的线程叫工作线程 第一:降低资源消耗。通过重复利用已创建的线程降低线程创建
  • 你能不能谈谈,java GC是在什么时候,对什么东西
    你能不能谈谈,java GC是在什么时候,对什么东西
    在什么时候: 1.新生代有一个Eden区和两个survivor区,首先将对象放入Eden区,如果空间不足就向其中的一个survivor区上放,如果仍然放不下就会引发一次发生
  • ThreadLocal(线程变量副本)
    ThreadLocal(线程变量副本)
    Synchronized实现内存共享,ThreadLocal为每个线程维护一个本地变量。 采用空间换时间,它用于线程间的数据隔离,为每一个使用该变量的线程提供一个副本,
  • 线程池的种类,区别和使用场景
    线程池的种类,区别和使用场景
    一个线程从被提交(submit)到执行共经历以下流程: 线程池判断核心线程池里是的线程是否都在执行任务,如果不是,则创建一个新的工作线程来执行任务
  • Java编程,打印昨天的当前时刻
    Java编程,打印昨天的当前时刻
    public class YesterdayCurrent{ public void main(String[] args){ Calendar cal = Calendar.getInstance(); cal.add(Calendar.DATE, -1); System.out.println(cal.getTime()); } }